The well-known 'Docker containers don't see each other' problem - docker

I checked many forum entries (e.g. in stackoverflow too) but I still cannot figure out what the problem is with my docker-compose file.
So when I start my application (content-app) I got the following exception:
Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=content-database)(port=3306)(type=master) : Connection refused (Connection refused)
My application is a Spring boot app that tries to connect to the database, the JDBC URL is
url: jdbc:mariadb://content-database:3306/contentdb?autoReconnect=true
The Spring Boot app works fine as locally (when no docker is used) can connect to the local mariadb.
So the content-app container don't see the content-database container. I read that if I specify a network and I assign the containers to the network then they should be able to connect to each other.
When I connect to the running content-app container then I can telnet to content-database
root#894628d7bdd9:/# telnet content-database 3306
Trying 172.28.0.3...
Connected to content-database.
Escape character is '^]'.
n
5.5.5-10.4.3-MariaDB-1:10.4.3+maria~bionip/4X#wW/�#_9<b[~)N.:ymysql_native_passwordConnection closed by foreign host.
My docker-compose yaml file:
version: '3.3'
networks:
net_content:
services:
content-database:
image: content-database:latest
build:
context: .
dockerfile: ./database/Dockerfile
networks:
- net_content
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
content-redis:
image: content-redis:latest
build:
context: .
dockerfile: ./redis/Dockerfile
networks:
- net_content
content-app:
image: content-app:latest
build:
context: .
dockerfile: ./content/Dockerfile
networks:
- net_content
depends_on:
- "content-database"
Any hint please?
Thanks!

I guess MariaDB is listening on default port 3307, this means your application has to connect to this port as well. I guess this is the case as you are mapping the port 3307 of your container to "the outside".
Change the port in your connection string:
url: jdbc:mariadb://content-database:3307/contentdb?autoReconnect=true

You have to expose the port on which content-database is listening in the Dockerfile at ./database/Dockerfile

Related

Docker compose container is not visible inside pgAdmin4

I created a docker file to create a pgAdmin4 container and a postgres container.
version: '3.8'
services:
postgres:
container_name: pg_container
image: postgres
restart: always
environment:
POSTGRES_USER: webquiver
POSTGRES_PASSWORD: webquiver
POSTGRES_DB: quiver_db
ports:
- "5432:5432"
pgadmin:
container_name: pgadmin4_container
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: admin
ports:
- "5050:80"
When running docker compose up I can go to the localhost:5050 to reach pgAdmin4 and login in with my credentials you can see in the code.
But when I use the dropdown menu for servers, it is empty. nothing is created. And I can not create any server there. It does not allow me to. I get the Error:
Unable to connect to server:
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and
accepting
TCP/IP connections on port 5432?
could not connect to server: Address not available
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
please help. THX ^^
greetings
I've reproduced your docker-compose file and everything is fine with it.
I'm guessing there is a misunderstanding how postgres and pgadmin are interacting with each other from scratch.
pgadmin is only the frontend that you can connect to a postgres database, it's not automatically searching for any existing postgres server.
I'm able to add the server inside the pgadmin with this host and port: postgres:5432 As inside the docker will resolve the service name as hostname postgres to the other service pgadmin.
This configuration will be lost, when the composition is restartet, as no volumes to persist the configuration are specified. Therefore, you have to follow steps from Importing-servers and repeat them every time you start the composition.
eg: build you own pgadmin image that specifies the json to import at startup
Use the docker compose build: property to specify a source
Ok after a night of sleep I found the issue. For the server Host I wrote the db name and not the real container name. So pgAdmin could not find the container.
Have a nice day. : )

Minio / Keycloak integration: connection refused

I am trying to connect MinIO with KeyCloak and I follow the instructions provided in this documentation:
https://github.com/minio/minio/blob/master/docs/sts/keycloak.md
What I have done so far is deploy a Docker container for the MinIO server, another one for the MinioClient and a third one used for the KeyCloak server.
As you can see in the following snippet the configuration of the Minio Client container is done correctly, since I can list the buckets available in the Minio Server:
mc ls myminio
[2020-05-14 11:54:59 UTC] 0B bucket1/
[2020-05-06 12:23:01 UTC] 0B bucket2/
I have an issue arising when I try to configure MinIO as depicted in step 3 (Configure MinIO) of the documentation. In more detail, the command that I run is this one:
mc admin config set myminio identity_openid config_url="http://localhost:8080/auth/realms/demo/.well-known/openid-configuration" client_id="account"
And the error I get is this one:
mc: <ERROR> Cannot set 'identity_openid config_url=http://localhost:8080/auth/realms/demo/.well-known/openid-configuration client_id=account' to server. Get http://localhost:8080/auth/realms/demo/.well-known/openid-configuration: dial tcp 127.0.0.1:8080: connect: connection refused.
When I curl this address http://localhost:8080/auth/realms/demo/.well-known/openid-configuration from the MinIO Client container though, I retrieve the JSON file.
Turns out, all I had to do is change the localhost in the config_url, from localhost to the IP of the KeyCloak container (172.17.0.3).
This is just a temporary solution that works for now, but I will continue searching for something more concrete than just hardcoding the IP.
When I figure out the solution, this answer will be updated.
Update
I had to create a docker-compose.yml file as the one below in order to overcome the issues without having to manually place the IP of the KeyCloak container.
version: '2'
services:
miniod:
image: minio/minio
restart: always
container_name: miniod
ports:
- 9000:9000
volumes:
- "C:/data:/data"
environment:
- "MINIO_ACCESS_KEY=access_key"
- "MINIO_SECRET_KEY=secret_key"
command: ["server", "/data"]
networks:
- minionw
mcd:
image: minio/mc
container_name: mcd
networks:
- minionw
kcd:
image: quay.io/keycloak/keycloak:10.0.1
container_name: kcd
restart: always
ports:
- 8080:8080
environment:
- "KEYCLOAK_USER=admin"
- "KEYCLOAK_PASSWORD=pass"
networks:
- minionw
networks:
minionw:
driver: "bridge"
Connection refused occurs when a port is not accessible on the hostname or IP we specified.
Please try exposing the port using --expose flag along with the port number which you wish to expose when using the docker CLI. Then being exposed, you can access on it on localhost

Using docker to setup tendermint testnet and establishing communication between abci and tendermint core

I am trying to integrate my own ABCI-application with the localnet. The docker-compose looks as
version: '3'
services:
node0:
container_name: node0
image: "tendermint/localnode"
ports:
- "26656-26657:26656-26657"
environment:
- ID=0
- LOG=${LOG:-tendermint.log}
volumes:
- ./build:/tendermint:Z
command: node --proxy_app=tcp://abci0:26658
networks:
localnet:
ipv4_address: 192.167.10.2
abci0:
container_name: abci0
image: "abci-image"
volumes:
- $GOPATH/src/samplePOC:/go/src/samplePOC
ports:
- "26658:26658"
build:
context: .
dockerfile: $GOPATH/src/samplePOC/Dockerfile
command: /go/src/samplePOC/samplePOC
networks:
localnet:
ipv4_address: 192.167.10.6
Both the nodes and the abci- containers are built successfully. The ABCI server is started successfully and the nodes are trying to make connections. However the main problem is that the I see the two are not able to communicate with each other.
I get the following error:
node0 |E[2019-10-29|15:14:28.525] abci.socketClient failed to connect
to tcp://abci0:26658. Retrying... module=abci-client connection=query
err="dial tcp 192.167.10.6:26658: connect: connection refused"
Can someone please help me here?
My first thought is that you may need to add a depends_on: ["abci0"] to node0, as the ABCI application must be listening before Tendermint will try to connect.
Of course, TM should continue to retry so this may not be the issue.
Another thing you can try, is to run tendermint on your host machine, and attempt to connect to the exposed port of ABCI port on abci0 (26658) to isolate the problem to the docker configuration.
If you're not able to run tendermint node --proxy_app=tcp://localhost:26658 the problem likely lies in your ABCI application.
I assume you've initialized a directory in the volume you mount into node0?
I got this working with the kvstore example from Tendermint.
version: "3.4"
services:
kvstore-app:
image: alpine
expose:
- "26658"
volumes:
- ./kvstore-example:/home/dev/kvstore-example
command: "/home/dev/kvstore-example --socket-addr tcp://kvstore-app:26658"
tendermint-node:
image: tendermint/tendermint
depends_on:
- kvstore-app
ports:
- "26657:26657"
environment:
- TMHOME=/tmp/tendermint
volumes:
- ./tmp/tendermint:/tmp/tendermint
command: node --proxy_app=tcp://kvstore-app:26658
I'm not exactly sure why your docker-compose.yml isn't working, but it's likely that you are not binding the socket of your abci application in a way that is accessible to the node. I'm explicitly telling the abci application to do so with the argument --socket-addr tcp://kvstore-app:26658". Additionally, I'm just exposing the port of the abci application on the docker network, but I think mapping the port should do this implicitly.
Also I would get rid of all the network stuff. Personally, I use the network configuration only if I have some very specific network goals in mind.

Docker container to container connect: connection refused

When all are run standalone outside of docker it works with no problem when core attempts to do a get from cerner. However, doing the same when all are dockerized as below I get:
Get http://cerner:8602/api/v1/patient/search: dial TCP 192.168.240.4:8602: connect: connection refused. The .4 is the IP of the cerner container and .2 is the IP of the core container
Cerner is the name of the container being called from core. If I change the name to the ip-address of the host server and use the ports, it works fine also. It just does not allow container to container using the containers DNS or IP. I have attempted with and without the private network and get the same thing.
The containers are all scratch go.
version: '3.7'
services: caConnector:
image: vertisoft/ca_connector:latest
ports:
- "8601:7001"
env_file:
- .env.ca_connector
networks:
- core-net
fhir:
image: vertisoft/fhir_connector:latest
container_name: cerner
ports:
- "8602:7002"
env_file:
- .env.fhir_connector
networks:
- core-net
core:
image: vertisoft/core:latest
ports:
- "8600:7000"
env_file:
- .env.core
networks:
- core-net
networks: core-net:
driver: bridge
You should call the container service with containerPort, not with hostPort in service to service communication. in your case, it should be 7000 to 7002 for any container to connect using container name.
Get http://cerner:8602/api/v1/patient/search: dial TCP
192.168.240.4:8602: connect: connection refused.
As in the error, it tries to attempt connection using publish port.
For example
version: "3"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
ports:
- "8001:5432"
When you run docker-compose up, the following happens:
A network called myapp_default is created.
A container is created
using web’s configuration. It joins the network myapp_default under
the name web. A container is created using db’s configuration. It
joins the network myapp_default under the name db.
In v2.1+, overlay
networks are always attachable
Each container can now look up the hostname web or db and get back the
appropriate container’s IP address. For example, web’s application
code could connect to the URL postgres://db:5432 and start using the
Postgres database.
It is important to note the distinction between HOST_PORT and CONTAINER_PORT. In the above example, for db, the HOST_PORT is 8001 and the container port is 5432 (postgres default). Networked service-to-service communication use the CONTAINER_PORT. When HOST_PORT is defined, the service is accessible outside the swarm as well.
Within the web container, your connection string to db would look like postgres://db:5432, and from the host machine, the connection string would look like postgres://{DOCKER_IP}:8001.
compose-networking

Conusume API from a client docker container to the server container

I have two different projects running on different docker containsers. Below the two YML files:
FILE webserver-api/docker-compose.yml
version: "3.1"
services:
webserver:
image: nginx:alpine
container_name: webserver-api
working_dir: /application
volumes:
- .:/application
- ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "8005:80"
FILE client-app/docker-compose.yml
version: '3'
services:
web:
container_name: client-app
build:
context: ./
dockerfile: deploy/web.docker
volumes:
- ./:/var/www
ports:
- "8010:80"
links:
- app
app: [...]
database: [...]
From the client-app I would like to call the webserver-api.
When I'm trying to consume the API from webserver-api I'm getting the message "cURL error connection refused" or timeout error.
For example
$response = file_get_contents('http:/localhost:8005/api/test');
I tried also to replace the localhost with the IP of the webserver-api container like this:
$response = file_get_contents('http://172.25.0.2:8005/api/test');
But still I get a timeout connection error.
Which is the correct URL of the server container to call form the client container? Or how to set the host URL?
Thanks a lot for the help and time.
You need create a network first. Then use this network for both your client and server docker compose. Otherwise the network is isolated.
Another approach is expose the port of server to localhost and connect to localhost from client side.
As per the docker-compose documentation
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
So ideally if your service are interdependent you should put them in a single compose file. In that case you could have accessed your service directly by name and container port
http://webserver/api/test
But since they are in separate compose file, you can access the service via host mapped port
$response = file_get_contents('http://localhost:8005/api/test');
it should also work.
To debug you can check
If port binding to 8005 is happening on your host.
The endpoint specified is correct and accessible from host.
Finally I figured it out.
By default docker creates a network called (in my case) webserver-api_default where webserver-api is the name of the folder that contains the YML file [projectname]_default.
On the client-app/docker-compose.yml of the client I had to specify which network to join:
version: '3'
networks:
default:
external:
name: webserver-api_default
web:
container_name: client-app
build:
context: ./
dockerfile: deploy/web.docker
volumes:
- ./:/var/www
ports:
- "8010:80"
links:
- app
app: [...]
database: [...]
And from the client container I have to make the call to the URL:
$response = file_get_contents('http://webserver-api:8005/api/test');
Where webserver-api is the name of the server container and not the name of the network.
https://docs.docker.com/compose/networking/

Resources