How can I connect to a Cassandra cluster running in Docker? - docker-compose

I am using bitnami/cassandra docker image for cassandra. I guess it is starting also, but I am not sure how to connect cassandra through any GUI or tool.
What is the host for cassandra? I tried localhost and container name but not able to connect. I tried checking cassandra.yml file from docker container and listen_address is something alphanumeric value. What would be the public ip so I can connect through GUI or cqlsh.
How can I configure public IP or listen_address in cassandra.yml file or after starting cassandra docker container how can I connect it through GUI or any code.
Below is my docker-compose
cassandra:
image: bitnami/cassandra:latest
container_name: "cassandra"
ports:
- '7000:7000'
- '9042:9042' # native protocol clients
volumes:
- ./data/cassandra:/bitnami
environment:
- CASSANDRA_USER=user
- CASSANDRA_PASS=password
- CASSANDRA_CQL_PORT_NUMBER=9042
- CASSANDRA_PASSWORD_SEEDER=yes

I didn't have any issues connecting to a Cassandra container running the Bitnami image.
You didn't provide details of what your issue was or steps to replicate the problems so I'm going to provide the steps I did in the hope that it will help you.
STEP 1 - Pull the Bitnami Cassandra Docker image:
$ docker pull bitnami/cassandra:latest
STEP 2 - Create a bridged network called cass-network:
$ docker network create cass-network --driver bridge
STEP 3 - Launch the Cassandra instance called bitnamicassandra:
$ docker run --rm -d \
--name bitnamicassandra \
-p 9042:9042 \
--hostname bitnamicassandra \
--network cass-network \
bitnami/cassandra
STEP 4 - Connect to the container to watch the Cassandra system.log and wait for startup to complete, specifically waiting for the node to listen for CQL connections:
INFO [main] 2023-02-10 05:45:01,138 PipelineConfigurator.java:126 - \
Starting listening for CQL clients on /0.0.0.0:9042 (unencrypted)...
Since I've exposed the CQL port (with --port 9042:9042), I can see on my Docker host that the port is mapped as I expected:
$ sudo lsof -nPi -sTCP:LISTEN | grep dock
com.docke 51936 erick 85u IPv6 0xddbfea4aa7f1e44f 0t0 TCP *:9042 (LISTEN)
com.docke 51969 erick 21u IPv4 0xddbfea4ba2125bef 0t0 ICMP *:*
NOTE: You can also use the Linux command netstat -tnlp.
STEP 5 - Connect to Cassandra using cqlsh:
$ cqlsh -u cassandra -p cassandra
Connected to My Cluster at 127.0.0.1:9042
[cqlsh 6.0.0 | Cassandra 4.1.0 | CQL spec 3.4.6 | Native protocol v5]
Use HELP for help.
cassandra#cqlsh>
If you update your original question with:
steps to replicate your issue,
full command you ran, and
full error message,
I'd be happy to review it.
For more info + examples, see the Bitnami Cassandra image page on Docker Hub. Cheers!

Related

Access local postgres database from podman container during build

I have a Spring Boot application that runs inside a container and needs to connect to a local Postgresql database.
Now it fails at build time, as that is the moment when it tries to configure Spring beans and to connect to database.
I have configured it like following:
spring
datasource:
initialization-mode: always
platform: postgres
url: jdbc:postgresql://192.168.122.1:5432/academy
username: myuser
password: mypassword
but it fails to connect.
How shall I configure Dockerfile/connection string?
I think you have at least two alternatives
Alternative 1: Connecting via Unix domain socket
If you could have Postgres listen on a Unix domain socket, you could then pass in that socket to the container with a bind-mount. Use podman run with one of the command-line arguments --volume or --mount.
Maybe something like:
--mount type=bind,src=/path/to/socket/on/host,target=/path/to/socket/in/container
If your system has SELINUX enabled, you would need to add the option Z
--volume /path/to/socket/on/host:/path/to/socket/in/container:Z
Alternative 2: Connecting via TCP socket
I think you could add the option
--network slirp4netns:allow_host_loopback=true
to the podman run command and connect to the IP address 10.0.2.2.
Quote "Allow the slirp4netns to reach the host loopback IP (10.0.2.2, which is added to /etc/hosts as host.containers.internal for your convenience)" from the podman run man page.
See also slirp4netns.1.md.
(The IP address 10.0.2.2 is a default value hard coded in the source code of slirp4netns).
Here is an example of a container that connects to a web server running on localhost:
esjolund#laptop:~$ curl -sS http://localhost:8000/file.txt
hello
esjolund#laptop:~$ cat /etc/issue
Ubuntu 20.04.2 LTS \n \l
esjolund#laptop:~$ podman --version
podman version 3.0.1
esjolund#laptop:~$ podman run --rm docker.io/library/fedora cur-l -sS http://10.0.2.2:8000/file.txt
curl: (7) Failed to connect to 10.0.2.2 port 8000: Network is unreachable
esjolund#laptop:~$ podman run --rm --network slirp4netns:allow_host_loopback=true docker.io/library/fedora curl -sS http://10.0.2.2:8000/file.txt
hello
esjolund#laptop:~$

docker confusion about port

I created a docker postgres container by using a compose file:
postgres:
image: postgres:12-alpine
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
init.sql:
CREATE USER test WITH PASSWORD '123456';
ALTER USER test WITH SUPERUSER;
CREATE DATABASE test;
I also created a pgAdmin4 container by running:
docker pull dpage/pgadmin4
docker run -p 5050:80 \
-e "PGADMIN_DEFAULT_EMAIL=user#domain.com" \
-e "PGADMIN_DEFAULT_PASSWORD=SuperSecret" \
-d dpage/pgadmin4
when setting up the connection in pgAdmin. I need to set up the server connection to 172.17.0.2 by looking at the postgres container IPAddress: docker container inspect 02e83f5f39d6 | grep IPAddress, using localhost as connection string will fail in pgAdmin4.
However, when I use python sqlalchemy, I could connect to localhost:5432.
import pandas as pd
from sqlalchemy import create_engine, MetaData
eng = create_engine('postgresql://test:123456#localhost:5432/test', echo=True)
meta = MetaData()
meta.reflect(eng, schema='public')
This is confusing. Why pgAdmin didn't recognize the port mapping? Is it because it is running from another container? What should be the correct set up then?
localhost is relative to the container / host.
For the pgAdmin container, localhost is itself. So you need to specify the IP to make pgAdmin point to the correct host.
Similarly for the python script running on your machine, localhost is the host machine (your PC). But since you specified the port mapping 5432:5432 the port on localhost:5432 is forwarded by docker the postgres containers port 5432. So if the script connects to localhost:5432 - it is forwarded to the container by docker.
There is nothing wrong for with this setup. Better would be have the pgAdmin container as part of the same compose file. With that you can utilize the name of the service as a DNS mapping to the container IP for easier management.

mongodb in docker ERR_CONNECTION_TIMED_OUT

Please help me with this. I tried the following steps, but I am not able to connect to MongoDB.
RUN: docker run -p 27017:27017 --name my-mongo -d mongo:latest
RUN: docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-mongo
The output of the above command is an IP-Address. Let the IP-Address is 172.17.0.2.
Open in browser this link: http://172.17.0.2:27017/
If the following output is displayed in a browser then everything is fine: It looks like you are trying to access MongoDB over HTTP on the native driver port. I am stuck here.
Thanks
The IP Address you are trying to access is the container's private ip that is only accessible from within the docker network.
Using the parameter -p that you're specifying on the docker run you're telling docker to map a local port on your host to the port specified on the container, in this case local port 27017 to container port 27017 and after that you can access it with localhost: http://localhost:27017
Read more about this here: https://docs.docker.com/config/containers/container-networking/

Unable to connect containerized app to containerized postgres, receiving dial tcp connection refused error

This community is my last resort for this problem, as I have been fighting with this for several hours now.
I have a go app running in one container, in the other container I am running a postgres db. I am able to connect to the postgres db from my go application as long as only my postgres is within a container, and my go app is running locally as usual. However, when my go app is trying to access the postgres from within a docker container i am getting the following error:
dial tcp 127.0.0.1:8080: connect: connection refused
Below I try to provide enough information, but will gladly add more if requested.
I have 2 docker containers running with the following ports:
go application, port info: 8081/tcp -> 0.0.0.0:8081
postgres db, port info: 5432/tcp -> 0.0.0.0:8080
I am running the go app with:
docker run -it --rm --name gographqlserver --link postgresdb:postgres -d -p 8081:8081 gogogopher;
and the postgres db with:
docker run -it --rm --name postgresdb -e POSTGRES_PASSWORD=hello123 -d -p 8080:5432 postgresimage;
both containers can be started without any problems.
I have also tried connecting both containers within a docker network, which did not help.
help would be immensely appreciated!
You are using localhost address within the container which is not the same as your host's address. You should do one of the following instead:
Use your actual host's IP from app's container
Use postgresdb container's IP with the native port (5432). You can discover this IP using docker inspect postgresdb.
Use postgresdb as host name and the native port (5432) when connecting both containers to the same network

How to connect to Cloud SQL (2nd Generation) via MySQL Proxy Docker Container over TCP

Running on Mac OS X, I have been trying to connect to a Cloud SQL instance via the proxy using these directions. Once you have installed the MySQL client, gce-proxy container, and have created a service account in Google Cloud Platform, you get down to running these two commands specified in the documentation:
docker run -d -v /cloudsql:/cloudsql \
-v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
-instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 -credential_file=[CLOUD_KEY_FILE_PATH]
mysql -h127.0.0.1 -uroot -p
First, I don't understand how this should ever work, since the container is not exposing a port. So unsurprisingly, when I attempted to connect I get the following error from the MySQL client:
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61)
But if I do expose the port by adding -p 3306:3306 to the docker run command, I still can't connect. Instead I get the following error from MySQL client:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
I have successfully connected to the proxy running cloud_sql_proxy on my docker host machine by following that documentation, so I am confident my credential file and my mysql client is configured correctly. The logs of the container do not state that any connection was attempted. I have no problem connecting to a normal mysql container via docker. What am I missing here?
I was able to figure out how to use cloudsql-proxy on my local docker environment by using docker-compose. You will need to pull down your Cloud SQL instance credentials and have them ready. I keep them them in my project root as credentials.json and add it to my .gitignore in the project.
The key part I found was using =tcp:0.0.0.0:5432 after the GCP instance ID so that the port can be forwarded. Then, in your application, use cloudsql-proxy instead of localhost as the hostname. Make sure the rest of your db creds are valid in your application secrets so that it can connect through local proxy being supplied by the cloudsql-proxy container.
Note: Keep in mind I'm writing a tomcat java application and my docker-compose.yml reflects that.
docker-compose.yml:
version: '3'
services:
cloudsql-proxy:
container_name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: /cloud_sql_proxy --dir=/cloudsql -instances=<YOUR INSTANCE ID HERE>=tcp:0.0.0.0:5432 -credential_file=/secrets/cloudsql/credentials.json
ports:
- 5432:5432
volumes:
- ./credentials.json:/secrets/cloudsql/credentials.json
restart: always
tomcatapp-api:
container_name: tomcatapp-api
build: .
volumes:
- ./build/libs:/usr/local/tomcat/webapps
ports:
- 8080:8080
- 8000:8000
env_file:
- ./secrets.env
restart: always
It does look like there are some omissions in the documentation.
1) As you point out, you need to expose the port from the container. You'll want to make sure you only expose it to the local machine by specifying -p 127.0.0.1:3306:3306.
2) Then when running the container, you'll want to expose the port outside the container by specifying -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306
I tried #Vadim's suggestion, which is basically this:
docker run -d -v /cloudsql:/cloudsql \
-p 127.0.0.1:3306:3306 \
-v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
-instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 -credential_file=[CLOUD_KEY_FILE_PATH]
I was still unable to get a connection, as I still got this error:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
However, the logs of the docker container showed a connection, like so:
2016/10/16 07:52:32 New connection for "[INSTANCE_CONNECTION_NAME]"
2016/10/16 07:52:32 couldn't connect to "[INSTANCE_CONNECTION_NAME]": Post https://www.googleapis.com/sql/v1beta4/projects/[PROJECT_NAME]/instances/[CLOUD_SQL_INSTANCE_NAME]/createEphemeral?alt=json: oauth2: cannot fetch token: Post https://accounts.google.com/o/oauth2/token: x509: failed to load system roots and no roots provided
So now it appeared that it was getting the traffic, but it not find the certificates for the SSL container. I had used OpenSSL's cert.pem export of my certificates and mounted it to the same location in the docker container. It makes sense that an arbitrary mapping of [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] wasn't helping the proxy figure out where the certificates were. So I used a clue from this Kubernetes setup guide and change the mounted volume to -v [LOCAL_CERTIFICATE_FILE_PATH]:/etc/ssl/certs. Mercifully, that worked.
TL;DR - Here is the final syntax for getting the Docker Container to run over TCP:
docker run -d \
-p 127.0.0.1:3306:3306 \
-v [SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY]:[SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY] \
-v [LOCAL_CERTIFICATE_DIRECTORY]:/etc/ssl/certs \
b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
-instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 \
-credential_file=[SERVICE_ACCOUNT_PRIVATE_KEY_JSON_FILE]