Docker-Compose Unable to connect to any of the specified MySQL hosts - mysql

i have an existing Project ( API - portal - Mysql )
i have used Docker-compose without dockerfile
i publish the API - Portal and put them all in folder and then Docker-compose up
i can reach the api by getting the local values in it
but if i tried to reach mysql trough the API using postman its not working even when i open the frontend website
ConnectionString:
"ConnectionString": "server=xmysql;port=4406;Database=sbs_hani;User ID=hani;Password=123456; persistsecurityinfo=True;Charset=utf8; TreatTinyAsBoolean=false;"
This is my docker-compose file :
version: '3'
services:
xmysql:
container_name: xmysql
hostname: xmysql
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: "sbs_hani"
MYSQL_USER: "hani"
MYSQL_PASSWORD: "123456"
ports:
- "3306:4406"
networks:
- xnetwork
volumes:
- data-volume:/var/lib/mysql
- ./hanimysql/sbs_hani.sql:/docker-entrypoint-initdb.d/sbs_hani.sql
xapi:
container_name: xapi
hostname: xapi
image: microsoft/dotnet:latest
# restart: always
tty: true
command: ["dotnet", "/var/lib/volhaniapi/hani.APIs.dll"]
ports:
- "8081:80"
- "8444:443"
networks:
- xnetwork
links:
- xmysql:xmysql
depends_on:
- xmysql
volumes:
- ./haniapi/:/var/lib/volhaniapi/
xportal:
container_name: xportal
hostname: xportal
image: microsoft/dotnet:latest
# restart: always
tty: true
command: ["dotnet", "/var/lib/volhaniportal/hani.Portal.dll"]
ports:
- "8083:80"
- "8446:443"
networks:
- xnetwork
links:
- xmysql:xmysql
depends_on:
- xmysql
volumes:
- ./haniportal/:/var/lib/volhaniportal/
xfront:
container_name: xfront
hostname: xfront
image: nginx:stable-alpine
# restart: always
ports:
- "8082:80"
- "4445:443"
networks:
- xnetwork
links:
- xapi:xapi
depends_on:
- xapi
volumes:
- ./hanifront/:/usr/share/nginx/html
volumes:
data-volume: {}
# xvolmysql:
# driver: "local"
# xvolmongo:
# driver: "local"
# xvolrabbitmq:
# driver: "local"
# xvolstarapi:
# driver: "local"
networks:
xnetwork:
driver: bridge

When you make a connection from one Docker container to another, you always connect to the port the service inside the container is actually listening on. Any ports: mappings are ignored (and in fact you don't need ports: if you don't want the service to be accessible from outside Docker container space).
In your example, you need to change the port number in the connection string to the default MySQL port 3306.
(Consider removing all of the container_name:, hostname:, networks:, and links: blocks in the file. You should have an equivalent container stack with the same functionality; the two most observable differences are that if you directly use docker commands then the container names will be prefixed with the directory names, and the Docker-internal network will be named default. You can still use the service block names like xmysql as host names.)

Related

Docker MySQL - cant connect SpringBoot app to MySQL database in docker container using docker-compose

Trying to connect Springboot app dicom_viewer: Imagename: sample with Mysql: Imagename: pb_mysql running in docker container. Error: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure.
Application.properties file:
#MySQL database connection strings
spring.datasource.url=jdbc:mysql://pb_mysql:3306/test?autoReconnect=true&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=pb
spring.datasource.password=pb#123
#JPA property settings
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
Docker-compose file:
version: '2'
services:
pb_mysql:
container_name: pb_mysql
restart: always
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: 'root123' # TODO: Change this
volumes:
- sql-datavolume:/var/lib/mysql
patient_browser:
container_name: patient_browser
restart: always
image: patient_browser
ports:
- 8080:8080
volumes:
- ./dicom_images:/usr/src/app/dicom_images
springboot-image:
container_name: dicom_viewer
restart: always
image: sample
ports:
- 8081:8080
volumes:
sql-datavolume:
networks:
f4:
driver: bridge
Dockerfile:
FROM openjdk:8-jdk-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY ./target/springboot-image-0.0.1-SNAPSHOT.jar /usr/src/app
COPY . /usr/src/app
EXPOSE 8080
ENTRYPOINT ["java","-jar","springboot-image-0.0.1-SNAPSHOT.jar"]
Database: test, table: pm_of_india
Docker images, docker ps -a
docker-compose up
Error: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
There are two things to notice,
depends_on
You kept pb_mysql ahead of others in the yaml configuration file. This does not ensure the mysql-server to be up and running ahead of others.
You want to use depends_on, so the depended pb_mysql will be initiated first.
ports
You are using bridged network, so you need to map 3306 to 3306 for mysql-server.
version: '2'
services:
patient_browser:
container_name: patient_browser
restart: always
image: patient_browser
ports:
- 8080:8080
volumes:
- ./dicom_images:/usr/src/app/dicom_images
- 8081:8080
depends_on:
- pb_mysql
springboot-image:
container_name: dicom_viewer
restart: always
image: sample
ports:
- 8081:8080
depends_on: # Let mysql-server start first
- pb_mysql
pb_mysql:
container_name: pb_mysql
ports:
- "3306:3306" # Port mapping.
restart: always
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: 'root123' # TODO: Change this
volumes:
- sql-datavolume:/var/lib/mysql
volumes:
sql-datavolume:
networks:
f4:
driver: bridge
I would avoid using restart: always unless I absolutely need it.
The rest looks good to me. Let me know if it is resolved.
You are not referencing your network.
Try adding it to your services i.e.:
services:
pb_mysql:
networks:
- f4
...

Docker Compose - Can't access Database

My Docker Wordpress Container some how cannot connect to my database container. I tried to pass the credentials through the environment key.
I'm using external volumes that stores the Data from my previous Wordpress build as well as the data from the Database.
docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
container_name: db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress_oxygen
volumes:
- wordpress_db-data:/var/lib/mysql
networks:
- conturas-network
wordpress:
depends_on:
- db
image: wordpress:5.6.0-fpm-alpine
container_name: wordpress
restart: unless-stopped
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress_oxygen
volumes:
- wordpress_data:/var/www/html
networks:
- conturas-network
webserver:
depends_on:
- wordpress
image: nginx:1.19.6-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- wordpress_data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- conturas-network
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress_data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email username#xyz.io --agree-tos --no-eff-email --force-renewal -d xyz.io -d www.xyz.io
volumes:
certbot-etc:
wordpress_data:
external: true
wordpress_db-data:
external: true
networks:
conturas-network:
driver: bridge
Error Logs from the db-container
...
2020-12-27T15:53:26.593191Z 2 [Note] Access denied for user 'wordpress_oxygen'#'172.30.0.3' (using password: YES)
Thanks for helping!
The very last line of the logs give the important hint on the underlying issue:
[Note] Access denied for user 'wordpress_oxygen'#'172.30.0.3' (using password: YES)
It means that the database credentials used to connect to the database are incorrect - i.e. the username/password combination.
But since this is logged by the database it means WordPress is actually able to connect to the database - i.e. your docker networks are setup correctly.
You should verify now that the values of configured credentials (WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD etc.) are actually correct - which is the same as MYSQL_USER and MYSQL_PASSWORD used at the time of initializing the database - that is, the environment variables MYSQL_USER, MYSQL_PASSWORD etc. are only used when the database volume is empty and needs to be initialized, see Environment Variables in the image description:
Do note that none of the variables below will have any effect if you start the container with a data directory that already contains a database: any pre-existing database will always be left untouched on container startup.
You may also try to re-initialize the database by deleting the volume and starting a fresh instance of the service.
Also note that environment and env_file two different ways of specifying environment variables for the service, but mixing those two is bad practice since it can lead to unexpected behavior.
If you want to import values from your .env file to use for variable substitution you don't need to "import" it with env_file since it is loaded automatically for docker-compose! I.e. your current configuration does not do what you probably think it does.
What I did to fix the issue
I removed the the environment keys from the whole compose file.
Why did I do this?
I realized with the help of #acran answers, that the volume that I passed into the docker-compose file, was already a ready to use copy of my Initial Wordpress build/installation the same goes for the MySQL Database. (This means all credentials was already stored inside of each volume) Because of that I was not able to pass environment-variables to the composition, to be more precise, you can pass environment-variables to a build but they would simple have no effect on the finished container build.
You can only set environment-variables at the initial build.
Result
version: '3.3'
services:
db:
image: mysql:5.7
container_name: db
restart: unless-stopped
volumes:
- wordpress_db-data:/var/lib/mysql
networks:
- my-network
wordpress:
depends_on:
- db
image: wordpress:5.6.0-fpm-alpine
container_name: wordpress
restart: unless-stopped
volumes:
- wordpress_data:/var/www/html
networks:
- my-network
webserver:
depends_on:
- wordpress
image: nginx:1.19.6-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress_data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- my-network
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress_data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email my.name#xyz.io --agree-tos --no-eff-email --expand --noninteractive -d xyz.io -d www.xyz.io -d dev.xyz.io
volumes:
certbot-etc:
wordpress_data:
external: true
wordpress_db-data:
external: true
networks:
my-network:
driver: bridge

use client to connect to mysql inside a docker network

I'm using docker swarm to create a small infrastructure with different wordpress instances, I have an ingress (nginx) and different stacks (wp,mysql,wp). The docker-compose for each stack is like this:
version: "3.7"
networks:
foo-frontend:
foo-backend:
volumes:
db_data:
wordpress_data:
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
env_file:
- db.env
networks:
- foo-backend
ports:
- "3306:3306"
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html/wp-content
env_file:
- wp.env
networks:
- foo-frontend
- foo-backend
nginx:
depends_on:
- wordpress
image: nginx:latest
volumes:
- ./nginx:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt
networks:
- foo-frontend
while the ingress is:
version: "3.7"
services:
nginx:
image: nginx:latest
ports:
- 80:80
- 443:443
volumes:
- ~/docker-vps/ingress/conf.d:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt
networks:
- foo-frontend
networks:
frontend:
external: true
my problem is that I'm not able to connect to mysql with my client, I tried to use the container ip with the right port but is not working....is there a way to connect to mysql with a client?
many thanks
Consider as hostname the name of service. This is how services communicate. So, the hostname of database is db. Let me know the error message that occurs, because I don't have rating to comment your original question to know this.

docker compose spring boot logs

I'm trying to run both a spring boot app and mysql in separate docker containers and I'm having trouble debugging issues because I can't see any logs. When I run docker-compose up I see the start up logs (Spring Boot banner) and see the app start, but after that no more logging. I'm getting a 404 hitting one of my end points but I can't debug it without seeing the logs.
docker-compose.yml:
version: "3.3"
services:
database:
build:
context: ./database
image: pensionator_db
# set default mysql root password, change as needed
environment:
MYSQL_USER: pensionatoruser
MYSQL_DATABASE: pensionatordb
# Expose port 3306 to host. Not for the application but
# handy to inspect the database from the host machine.
ports:
- "3306:3306"
restart: always
appserver:
build:
context: .
dockerfile: app/src/main/docker/Dockerfile
image: pensionator_app
# mount point for application in tomcat
# open ports for tomcat and remote debugging
ports:
- "8080:8080"
- "8000:8000"
restart: always
How do I get logging to work?
There was nothing wrong with the logging, the issue was with my docker-compose.yml file. I needed to link the database correctly.
docker-compose.yml:
version: '3'
services:
database:
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_USER: root
MYSQL_DATABASE: pensionator
ports:
- '3307:3306'
restart: always
appserver:
build:
context: .
dockerfile: src/main/docker/Dockerfile
depends_on:
- database
image: pensionator_app
environment:
SPRING_DATASOURCE_URL: 'jdbc:mysql://database:3306/pensionator'
links:
- database
ports:
- '8080:8080'
- '8000:8000'
restart: always

docker nodejs container cant connect mysql container

I'm running Docker server in Digital Ocean. There I have two containers Nodejs and Mysql. Mysql container has open port to 3306.
When trying to access mysql via nodejs by Docker Server ip + port. I get Error: connect ETIMEDOUT.
When I run same nodejs docker setup in my local computer it works fine. Is there something i'm missing?
Here is nodejs docker-composer.yml:
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST=192.168.11.207 #or public ip in internet
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
Here is docker-composer.yml for mysql
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
I'll modify answer as we advance - Following your comments, while I can not access to your env, lets try to solve this incrementally:
Let's make the db visible to the node.js server
See how it works and then probably dive into env networking configuration.
There 2 ways to solve 1st and may be 2nd problem as i see without being able to touch your env:
1st one will ensure that the server sees the database, but if you can not connect to the db from outside seems there firewall/droplet networking configuration issue, and you can try 2nd way (wont likely to change, but it's good to try). This assumes you use same docker compose and same bridge cusom network:
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST= mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
networks:
inner:
alias: server
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "<externalEnvIp>:3036:3306"
restart: always
networks:
inner:
alias: mysql
networks:
inner:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
ipam:
driver: default
config:
- subnet: 172.16.100.0/24
gateway: 172.16.100.1
Option 2 :
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST= mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
network_mode: "host"
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
network_mode: "host"
More precise solution (to find the roots of the problem) would involve into deep digging into your env network configuration, docker networking settings etc., but those solutions may help and fix your problem for now.
Pleasse after you try please output the results.
The docker networking doesn't allow you to go from inside a container back out to the host IP to connect to a port exposed by another container. I haven't dug into this enough to see if that's due to the iptables rules or perhaps something inside of docker-proxy. Either way, it's never been worth investigating since container-to-container networking is a built in feature of docker.
To use docker's networking, the containers need to be on the same docker network, and you reference them by their container name in DNS. With docker-compose, normally you can use the service name in place of the container name (e.g. test-web-install and mysql from your examples) since compose creates an alias for these. However, since you've overridden the container name for mysql, use your flask_mysql container name instead.
In your scenario, since you've split up the startup with two separate docker-compose.yml files, you'll be on separate networks created by compose. You have two options to resolve this:
Merge the two into a single docker-compose.yml (BlackStork gave an example of this).
Use an externally defined network that you create in advance.
To do the latter, first create your network:
docker network create dbnet
Then update your docker-compose.yml for the app to look like:
version: '2'
networks:
dbnet:
external: true
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST=flask_mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
networks:
- dbnet
And the docker-compose.yml for mysql:
version: '2'
networks:
dbnet:
external: true
services:
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
networks:
- dbnet