Docker container communication with other container on diffirent host/server - docker-compose

I am having two servers (CentOS8).
On server1 I have mysql-server container and on server2 I have zabbix-front-end i.e zabbix-web-apache-mysql (container name zabbixfrontend).
I am trying to connect to mysql-server from zabbixfrontend container. Getting error
bash-4.4$ mysql -h <MYSQL_SERVER_IP> -P 3306 -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to MySQL server on '<MYSQL_SERVER_IP>' (115)
When I do nc from zabbixfrontend container to my mysql-server IP I get "No route to host." error message.
bash-4.4$ nc -zv <MYSQL_SERVER_IP> 3306
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: No route to host.
NOTE : I am successfully do nc from the host machine (server2) mysql-server container.
docker-compose.yml
version: '3.5'
services:
zabbix-web-apache-mysql:
image: zabbix/zabbix-web-apache-mysql:centos-8.0-latest
container_name: zabbixfrontend
#network_mode: host
ports:
- "80:8080"
- "443:8443"
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./zbx_env/etc/ssl/apache2:/etc/ssl/apache2:ro
- ./usr/share/zabbix/:/usr/share/zabbix/
env_file:
- .env_db_mysql
- .env_web
secrets:
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_ROOT_PASSWORD
# zbx_net_frontend:
sysctls:
- net.core.somaxconn=65535
secrets:
MYSQL_USER:
file: ./.MYSQL_USER
MYSQL_PASSWORD:
file: ./.MYSQL_PASSWORD
MYSQL_ROOT_PASSWORD:
file: ./.MYSQL_ROOT_PASSWORD
docker logs zabbixfrontend out as below
** Deploying Zabbix web-interface (Apache) with MySQL database
** Using MYSQL_USER variable from ENV
** Using MYSQL_PASSWORD variable from ENV
********************
* DB_SERVER_HOST: <MYSQL_SERVER_IP>
* DB_SERVER_PORT: 3306
* DB_SERVER_DBNAME: zabbix
********************
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...
**** MySQL server is not available. Waiting 5 seconds...

The nc message is telling the truth: No route to host.
This happens because when you deploy your front-end container in the docker bridge network, its IP address belongs to the 172.18.0.0/16 subnet and you a are trying to reach an the database via an IP address that belongs to a different subnet (10.0.0.0/16).
On the other hand, when you deploy your front-end container on the host network, you no longer face that problem, because now the IP is literally using the IP address of the host machine, 10.0.0.2 and there is no need for a route to be explicitly created to reach 10.0.0.3.
Now the problem you are facing is that you can no longer access the web-ui via the browser. This happens because I assume you kept the ports:" option in your docker-compose.yml and tried to access the service on localhost:80/443. The source and destination ports do not need to be specified if you run the container on the host network. The container will just listen directly on the host on the port that's opened inside the container.
Try to run the front-end container with this config and then access it on localhost:8080 and localhost:8443:
...
network_mode: host
# ports:
# - "80:8080"
# - "443:8443"
volumes:
...
Running containers on the host network is not something that I would usually recommend, but hence your setup is quite special, having one container running on one docker host and another container running in another independent docker host, I assume you don't want create an overlay network and eventually register the two docker hosts to a swarm.

Related

Can't connect to DB located in docker container

I'm trying to create PostgreSQL DB inside docker container and connect to it from my local machine. Running docker-compose up -d with that inside docker-compose.yml:
version: '3.5'
services:
db:
image: postgres:12.2
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_DB: db
POSTGRES_USER: root
POSTGRES_PASSWORD: root
ended successfully. No crashes, errors of something. But, when I'm trying to connect to it with pgAdmin4 with these credentials:
Host name/address: localhost
Port: 5432
Maintenance database: db
Username: root
Password: root
it says to me:
Unable to connect to server:
FATAL: password authentication failed for user "root"
My OS: Windows 10 build(1809)
PostgreSQL version (installed on local machine): 12
Docker version: 19.03.13, build 4484c46d9d
UPD 1:
After re-creating container with different ports (now it is 5433:5433), pgAdmin4 error changed:
Unable to connect to server:
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
Host name/address: localhost
Port: 5432
You are trying to connect to 5432 port on localhost. Are you sure your container is taking the host IP?
To make the container run with the host IP run the container with --network host option.
docker run --network host <rest of the command>
Note that if you use '--network host' option, then portmapping '-p' option is not needed.
Read https://docs.docker.com/network/host/ for more information.
Have you checked you've cleaned away any old instances running locally and that you're not trying to access an old instance?
You can wipe out all local docker containers with: docker rm -f $(docker ps -aq)
Once you've got a clean environment you can try spin up the containers again locally and see if you can access the service. I copy/pasted what you have into a clean docker-compose.yaml and ran docker-compose up against the file - it worked and I logged in and was able to view the pg_user table.
If it still fails you can try to find the IP using: netstat -in | grep en0 which will show something like
en0 1500 192.168.1 **192.168.1.163** 15301832 - 9001208 - - -
this shows the external/accessible IP of the container. Try using the address shown (something similar to 192.168.1.163) instead of localhost

Can't access Postgres running with docker-compose from WebStorm (JetBrains)

I have the following docker-compose.yml:
version: '3.7'
services:
postgres-service:
image: postgres:12.3
env_file:
- .env
ports:
- '5432:5432'
volumes:
- /postgres/data/
This is my .env:
POSTGRES_USER=app_postgres_user
POSTGRES_PASSWORD=foobar
POSTGRES_DB=app_database
I know postgres-service is working because I connect manually to the service and it works with following commands:
docker-compose run postgres-service bash # connect to postgres-service
psql --host=postgres-service --username=app_postgres_user --dbname=app_database
But when I try to connect from within "Webstorm > Database" I get this error:
The connection attempt failed.
java.net.UnknownHostException: postgres-service.
Screenshot:
If Webstorm is running on the same host as the container, replace postgres-service with localhost.
If it is running elsewhere, replace postgres-service with the IP address of the docker host machine where the container resides.
I used your docker-compose and connected with DBeaver with these settings:
Your postgres container resides in a virtual network (e.g.: 172.17.0.0/16). By default there is no route from your machine to that network.
When you use
ports:
- 'src:dest'
...in your docker-compose.yml file, a DNAT rule is created from your host:src to the container:dest and that's the reason of using localhost:src or the IP address of the docker host.

docker: get container's external IP

Running several docker containers including postgres database remotely.
$docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------------
fiware-cygnus /cygnus-entrypoint.sh Up (healthy) 0.0.0.0:5050->5050/tcp, 0.0.0.0:5080->5080/tcp
fiware-elasticsearch /docker-entrypoint.sh elas ... Up 9200/tcp, 9300/tcp
fiware-grafana /run.sh Up 0.0.0.0:53153->3000/tcp
fiware-iotagent pm2-runtime bin/lwm2mAgent ... Up (healthy) 0.0.0.0:4041->4041/tcp, 5684/tcp, 0.0.0.0:5684->5684/udp
fiware-memcached docker-entrypoint.sh memca ... Up 11211/tcp
fiware-mongo docker-entrypoint.sh --bin ... Up 0.0.0.0:27017->27017/tcp
fiware-nginx nginx -g daemon off; Up 0.0.0.0:53152->53152/tcp, 80/tcp
fiware-orion /usr/bin/contextBroker -fg ... Up (healthy) 0.0.0.0:1026->1026/tcp
fiware-postgres docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
fiware-wirecloud /docker-entrypoint.sh Up (healthy) 8000/tcp
I want to get the external IP address of the fiware-postgres container so I can connect via pgAdmin, instead of managing db via postgres client. It appears the IPAddress of fiware-postgres is only accessible internally.
$docker inspect fiware-postgres | grep "IPAddress"
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.19.0.3",
pgAdmin error:
Unable to connect to server:
could not connect to server: Operation timed out
Is the server running on host "172.19.0.3" and accepting
TCP/IP connections on port 5432?
Is there a way to get it's external IP, or at least some way of connecting via pgAdmin (remember docker container run on a remote, accessed via ssh).
EDIT
The remote host is accessible via ssh root#193.136.x.x:2222 so the postgres port 5432 cannot be reached.
pgAdmin settings(Connection Tab):
Host: 193.136.xx.xx
Port: 5432
Maintenance database: postgres
Username: postgres
Password: password
pgAdmin error:
Unable to connect to server:
could not connect to server: Operation timed out
Is the server running on host "193.136.x.x" and accepting
TCP/IP connections on port 5432?
postgres service definition (in docker-compose):
postgres:
restart: always
image: postgres:10
hostname: postgres
container_name: fiware-postgres
expose:
- "5432"
ports:
- "5432:5432"
networks:
- default
environment:
- "POSTGRES_PASSWORD=password"
- "POSTGRES_USER=postgres"
- "POSTGRES_DB=postgres"
volumes:
- ./postgres-data:/var/lib/postgresql/data
build:
context: .
shm_size: '2gb'
Assuming that you have exposed the ports of your container to the underlying host, then the application is accessible via the IP address of the underlying host.
The 172.19.0.3 IP address is an IP address that exists inside the Docker network on the host: it's not available externally. If your remote host has IP 1.2.3.4 and your application port has been exposed, e.g. in your compose file you have something like:
ports:
- "5432:5432"
Then your application should be accessible via 1.2.3.4:5432.
EDIT:
If you are connecting from your local machine to the remote server using pgAdmin, then there should be no need to ssh: you should find that the service is still available at 1.2.3.4:5432. However, if you have some form of firewall in the way (e.g. you're sshing in to an AWS server), then access to 5432 on the remote host may well be blocked. In that case, consider using port forwarding to route connections on your local server to the remote server, via the ssh connection.
ssh -L 5432:193.136.x.x:5432 193.136.x.x:2222
Now connect using pgAdmin to localhost:5432 or 127.0.0.1:5432.
Here's the solution that works for me:
ssh -p 2222 root#193.136.xx.xx -L 5432:localhost:5432
postgres server finally accessible via pgAdmin

Could not connect to Postgres from Symfony 4 + Docker

I run into the strange problem. I've created docker-compose file to build php + nginx + postgres services:
version: '2'
services:
db:
image: orchardup/postgresql
ports:
- "5433:5432"
environment:
LC_ALL: C.UTF-8
POSTGRESQL_USER: postgres
POSTGRESQL_DB: db
POSTGRESQL_PASS: postgres
php:
build: .docker/php-fpm
ports:
- "9002:9002"
volumes:
- .:/var/www/symfony:cached
- ./var/log/symfony:/var/www/symfony/var/log:cached
links:
- db
nginx:
build: .docker/nginx
ports:
- "8001:80"
links:
- php
volumes_from:
- php
volumes:
- ./var/log/nginx/:/var/log/nginx:cached
After that I created DB schema by running bin/console doctrine:schema:update --force . The tables and migrations created just fine. Seems like DB connection is ok. I checked this by connecting to db from my machine through psql with credentials from .env, the tables are there.
But when I go to the web page and trying to authorize, I get an error told me the connection is not ok:
Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5433?"
I checked in both case I have dev environment - from the web page and from the console. I tried 5433 and 5432 ports with no success. I tried everything I could find for 3 hours.
This is the output from the postgres container:
# netstat -tlpn | grep 5432
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN 12/postgres
tcp6 0 0 :::5432 :::* LISTEN 12/postgres
# grep listen /etc/postgresql/9.3/main/postgresql.conf
listen_addresses = '*' # what IP address(es) to listen on;
The only way for containers to talk to each other is through IPs. By linking multiple containers together through --link (or links in docker-compose), docker creates a secure tunnel between those two containers so that we don't need to expose any ports externally.
If you try to connect to your database from your local environment through a database client, you will be able to connect to it from 127.0.0.1:5433 as the port is exposed to your host through the docker-compose file. This is the reason why your schema update command succeeded.
Docker exposes connectivity information for the source container to
the recipient container in two ways:
Environment variables,
Updating the /etc/hosts file.
Ref: https://docs.docker.com/network/links/#communication-across-links
In order to connect to your database (which is running in the db container) from the php container, you will need to get the host of your db container through the environment variable DB_PORT_5432_TCP_ADDR (I might be wrong on this, but type env in your php container's terminal to verify. You will need to SSH into your php container).
Alternatively, you can use the second method, which is just db as the hostname instead of 127.0.0.1 since docker updated the /etc/hosts file in the php container to map your linked container's name to its IP, and in this case, the value mapped to the hostname db is the same as the value stored in the environment variable DB_PORT_5432_TCP_ADDR.

How to connect Postgresql Docker Container with another Docker Container

I want to connect mysoft docker container to postgresql docker container.
But i have some errors:
ERROR: for mysoft_db_1 Cannot start service db: driver failed programming external connectivity on endpoint mysoft_db_1 (XXX):
Error starting userland proxy: listen tcp 0.0.0.0:5432: bind: address already in use
ERROR: for db Cannot start service db: driver failed programming external connectivity on endpoint mysoft_db_1 (XXX):
Error starting userland proxy: listen tcp 0.0.0.0:5432: bind: address already in use
here is my docker-compose.yml
version: '2'
services:
mysoft:
image: mysoft/mysoft:1.2.3
ports:
- "80:8080"
environment:
- DATABASE_URL=postgres://mysoft:PASSWORD#db/mysoft?sslmode=disable
db:
image: postgresql
environment:
- POSTGRES_USER=mysoft
- POSTGRES_PASSWORD=PASSWORD
- POSTGRES_DB=mysoft
ports:
- 5432:5432
I want use another, already running docker pg server to connect new soft, also one pg docker server, for more projects
Is it possible?
You should add links to the definition of mysoft service in docker-compose.yml. Then your db service will be accessible from mysoft container.
After that your service definition will look like this.
mysoft:
image: mysoft/mysoft:1.2.3
ports:
- "80:8080"
environment:
- DATABASE_URL=postgres://mysoft:PASSWORD#db/mysoft?sslmode=disable
links:
- db
Now about error of binding. Probably, you receive it, because you have a local postgresql running on port 5432 or you already have a running docker container with 5432 port mapped to local machine.
ports:
- 5432:5432
It is used for mapping ports to your local machine. And if you don't need to access container's db from it, just remove it.
I want use another, already running docker pg server to connect new
soft, also one pg docker server, for more projects Is it possible?
Yes, it's possible. Use external_links.
If you choose this option:
Remove the db service and links in mysoft service definition from your docker-compose.yml
Add external_links with correct container name to mysoft service definition.
Update host and port in DATABASE_URL according to the container name and postgresql port in it.
You might want to check of you already have a local postgres running on port 5432? If you do you can not do the ports 5432:5432 but have to expose the inner port to an other outer port e.g. 5555:5432
at least if you are using native docker (running on localhost)...