Cannot connect to Cassandra running in a Docker container

Viewed 554

For my application, there is a Docker container database which runs Cassandra. I expose the ports 9160 and 9042 to the host machine, but for some reason, I cannot connect to Cassandra from my host. I am able to connect to it from other Docker containers using cqlsh only if I put the other container in the same network.

My docker-compose file (which I run with docker-compose up):

  database:
    image: cassandra
    container_name: database
    depends_on:
      - kafka
    ports:
      - 9042:9042
      - 9160:9160
    volumes:
      - ./:/code
    environment:
      - CASSANDRA_START_RPC=true
      - CASSANDRA_BROADCAST_ADDRESS=database
    entrypoint: "/code/scripts/cassandra.sh"

  frontend:
    container_name: frontend
    build:
      context: driver/
    volumes:
      - ./:/code
    network_mode: service:database
    environment:
      - BOOTSTRAP_SERVER=kafka:9092
      - CASSANDRA_HOST=localhost
    entrypoint: "/code/scripts/frontend.sh"

where cassandra.sh and frontend.sh simply initialise the database by running a script, and installing some packages respectively.

Using the above setup, I am able to use cqlsh by simply calling cqlsh in the frontend container. If, however, I remove the line network_mode: service:database from frontend, and try to connect using cqlsh database or cqlsh $CASSANDRA_HOST, even after I set CASSANDRA_HOST=database. Doing any of the aforementioned commands gives me:

Connection error: ('Unable to connect to any servers', {'172.27.0.5:9042': ConnectionRefusedError(111, "Tried connecting to [('172.27.0.5', 9042)]. Last error: Connection refused")}).

As a result, I am not able to run cqlsh from my host machine either, even though I exposed the port 9042. The host machine is a 2020 iMac running macOS Monterey 12.3.1.:

> netstat -anvp tcp | awk 'NR<3 || /LISTEN/'
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)     rhiwat shiwat    pid   epid  state    options
tcp46      0      0  *.29092                *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp4       0      0  127.0.0.1.9042         *.*                    LISTEN      131072 131072   7099      0 0x0100 0x00000006
tcp4       0      0  127.0.0.1.7000         *.*                    LISTEN      131072 131072   7099      0 0x0100 0x00000006
tcp4       0      0  127.0.0.1.54196        *.*                    LISTEN      131072 131072   7099      0 0x0100 0x00000006
tcp4       0      0  127.0.0.1.7199         *.*                    LISTEN      131072 131072   7099      0 0x0100 0x00000006
tcp46      0      0  *.8080                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp46      0      0  *.7077                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp46      0      0  *.4040                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp46      0      0  *.9160                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp46      0      0  *.9042                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp46      0      0  *.2181                 *.*                    LISTEN      131072 131072    911      0 0x0100 0x00000006
tcp4       0      0  127.0.0.1.6463         *.*                    LISTEN      131072 131072   1241      0 0x0100 0x00000106
tcp4       0      0  127.0.0.1.49390        *.*                    LISTEN      131072 131072    826      0 0x0100 0x00000106
tcp4       0      0  127.0.0.1.45623        *.*                    LISTEN      131072 131072    826      0 0x0100 0x00000106
tcp4       0      0  127.0.0.1.49380        *.*                    LISTEN      131072 131072    826      0 0x0100 0x00000106
tcp4       0      0  127.0.0.1.49379        *.*                    LISTEN      131072 131072    826      0 0x0100 0x00000106
tcp4       0      0  127.0.0.1.15292        *.*                    LISTEN      131072 131072    770      0 0x0000 0x0000020f
tcp6       0      0  *.5000                 *.*                    LISTEN      131072 131072    465      0 0x0100 0x00000006
tcp4       0      0  *.5000                 *.*                    LISTEN      131072 131072    465      0 0x0100 0x00000006
tcp6       0      0  *.7000                 *.*                    LISTEN      131072 131072    465      0 0x0100 0x00000006
tcp4       0      0  *.7000                 *.*                    LISTEN      131072 131072    465      0 0x0100 0x00000006
tcp6       0      0  *.49198                *.*                    LISTEN      131072 131072    494      0 0x0100 0x00000006
tcp4       0      0  *.49198                *.*                    LISTEN      131072 131072    494      0 0x0100 0x00000006

I've spent hours looking for a solution for this and have viewed nearly every possible post on StackOverflow and other sites on this topic, but none of the solutions work for me. I would greatly appreciate some help.

1 Answers

The issue was caused by setting the entrypoint:

entrypoint: "/code/scripts/cassandra.sh"

As it turns out, some Cassandra settings are only initialised by the image if no entrypoint is provided. If one is provided, you must set these settings yourself, which I didn't do. I added the entrypoint cassandra.sh because I wanted to initialise the database by running a file create.cql:

#!/bin/sh
cassandra -R

# Wait for Cassandra to start up
while ! cqlsh -e 'describe cluster' ; do
    sleep 1
done

echo "Cassandra has started"

cqlsh --file '/code/scripts/create.cql'

echo "Cassandra has been initialised"

tail -f /dev/null

I ended up creating another Docker container that simply initialises the database once the database has started up:

database:
  image: cassandra
  container_name: database
  depends_on:
    - kafka
  ports:
    - 9042:9042
    - 9160:9160
  volumes:
    - ./:/code

db_seeder:
  container_name: db_seeder
  build:
    context: db_seeder/
  depends_on:
    - database
  volumes:
    - ./:/code
  environment:
    - CASSANDRA_HOST=database
  entrypoint: "/code/scripts/cassandra.sh"
Related