My aim is to connect two docker containers: one is a simple microservice, a Spring Boot App, another is a simple MySQL database running in docker container at local machine in Windows 10. After spending literally like 16 hours trying to connect my Spring Boot App and reading it everywhere possible and looking for solution in StackeOverflow, elsewhere in internet and in ChatGTP I still cannot find a solution how to make the connection to database in another container. I seeing people ask this question and when I tried answers that helped them, it is not working for me. All the time I’m getting the same problem: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
I have docker-compose.yaml:
version: '3.7'
services:
docker-mysql:
image: mysql:latest
ports:
- "3307:3306"
environment:
MYSQL_DATABASE: wallet_microservice
MYSQL_ROOT_PASSWORD: root
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
volumes:
- ./src/main/resources/data/schema.sql:/docker-entrypoint-initdb.d/schema.sql
myapp:
build:
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://docker-mysql:3306/wallet_microservice?autoReconnect=true&useSSL=false
depends_on:
- docker-mysql
Dockerfile:
FROM eclipse-temurin:17
WORKDIR /app
COPY build/libs/*.jar app.jar
CMD ["java", "-jar", "app.jar"]
application.properties in the Spring boot app:
spring.datasource.url=jdbc:mysql://docker-mysql:3306/wallet_microservice
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
I could successfully connect to the database running in this container from the same Spring boot app if I run the app in localhost at the same machine as docker, then I only change datasource line in app’s application.properties to
spring.datasource.url=jdbc:mysql://localhost:3307/wallet_microservice
When I was consulting with ChatGTP for troubleshooting I got feedback: (all the things seems to be fine) Network Configuration:
I suspect that this is because your app is trying to connect to the database before it is fully initialised.
version: '3.7'
services:
docker-mysql:
image: mysql:latest
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 5
myapp:
image: mysql:latest
container_name: myapp
depends_on:
docker-mysql:
condition: service_healthy
command: mysql -h docker-mysql -u root -p'root' -e 'SHOW DATABASES;'
You need to use depends_on
but it's not enough to check that the database service has started. You need to ensure that the actual database has initialised and is ready to accept connections.
So create a healthcheck
for the database service that will only pass once you are able to ping the database. Then make your app wait for the service to be marked as "healthy".
In the docker-compose.yml
I have replaced your app with a container that simply connects to the database and executes a simple SQL query. This will demonstrate that the database service is ready.
You can fiddle with the values for interval
, timeout
and retries
but the values supplied are a reasonable starting point.