Reputation: 53
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.
Upvotes: 3
Views: 3091
Reputation: 19
Solution
The command "docker pull cassandra:latest" is utilizing Docker, a containerization platform, to download the latest version of the Cassandra database management system (DBMS) image from the official Docker Hub repository. In technical terms:
Docker: A platform that enables developers to package applications and their dependencies into lightweight, portable containers. Containers provide a consistent environment across different environments, making it easier to deploy and scale applications.
pull: This Docker command is used to fetch container images from a container registry. In this case, it's pulling the Cassandra image.
cassandra:latest: Specifies the image to be pulled. "cassandra" is the name of the Docker image for the Cassandra DBMS, and ":latest" indicates that the latest available version of the image should be retrieved.
Docker Hub: A cloud-based registry service where Docker users can share and access container images. The official Cassandra image is hosted on Docker Hub.
So, when you run "docker pull cassandra:latest," Docker will download the most recent version of the Cassandra image from Docker Hub, making it available for local use on your machine. docker pull cassandra:latest
Now for the command:
docker run --name cassandra -p 127.0.0.1:9042:9042 -p 127.0.0.1:9160:9160 -d cassandra
The command you provided is a Docker command used to run a Cassandra container. Let's break it down in technical terms:
docker run: This command is used to create and start a new container based on a specified image.
--name cassandra: Assigns the name "cassandra" to the newly created container. This is helpful for referencing the container in subsequent Docker commands.
-p 127.0.0.1:9042:9042: Maps the container's port 9042 (Cassandra's native transport port) to the host machine's port 9042. This means you can access Cassandra on the host machine at 127.0.0.1:9042.
-p 127.0.0.1:9160:9160: Maps the container's port 9160 (used for Thrift communication) to the host machine's port 9160. This allows you to interact with Cassandra using Thrift on the host machine at 127.0.0.1:9160.
-d: Runs the container in the background (detached mode), allowing you to continue using the terminal.
cassandra: Specifies the name of the Docker image to use for creating the container. In this case, it's the Cassandra image.
So, when you run the command "docker run --name cassandra -p 127.0.0.1:9042:9042 -p 127.0.0.1:9160:9160 -d cassandra," it starts a new Cassandra container with specified port mappings, making Cassandra accessible on the host machine at the provided ports.
Utilising this command will make the (com.datastax.driver.core.exceptions.TransportException: [/127.0.0.1:9042] Cannot connect))
Exception to disappear like magic!
How Connect to Cassandra CQL Shell ?
artwellmamvura@Artwells-MacBook-Pro ~ % docker exec -it cassandra cqlsh
Connected to Test Cluster at 127.0.0.1:9042
[cqlsh 6.1.0 | Cassandra 4.1.3 | CQL spec 3.4.6 | Native protocol v5]
Use HELP for help.
cqlsh>
Upvotes: 2
Reputation: 53
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"
Upvotes: 1