Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot + docker-compose + MySQL: Connection refused

I'm trying to set up a Spring Boot application that depends on a MySQL database called teste in docker-compose. After issuing docker-compose up, I'm getting:

Caused by: java.net.ConnectException: Connection refused (Connection refused)

I'm running on Linux Mint, my docker-compose version is 1.23.2, my Docker version is 18.09.0.

application.properties

# JPA PROPS
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

spring.datasource.url=jdbc:mysql://db:3306/teste?useSSL=false&serverTimezone=UTC
spring.datasource.username=rafael
spring.datasource.password=password

spring.database.driverClassName =com.mysql.cj.jdbc.Driver

docker-compose.yml

version: '3.5'
services:
  db:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=rootpass
      - MYSQL_DATABASE=teste      
      - MYSQL_USER=rafael
      - MYSQL_PASSWORD=password
    ports:
      - 3306:3306
  web:
    image: spring-mysql
    depends_on:
      - db
    links:
      - db
    ports:
      - 8080:8080
    environment:
      - DATABASE_HOST=db
      - DATABASE_USER=rafael
      - DATABASE_NAME=teste
      - DATABASE_PORT=3306

and the Dockerfile

FROM openjdk:8
ADD target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
like image 516
Rafael A P Nascimento Avatar asked Jan 11 '19 11:01

Rafael A P Nascimento


1 Answers

Docker compose always starts and stops containers in dependency order, or sequential order in the file if not given. But docker-compose does not guarantee that it will wait till the dependency container is running. You can refer here for further details. So the problem here is that your database is not ready when your spring-mysql container tries to access the database. So, the recommended solution is you could use wait-for-it.sh or similar script to wrap your spring-mysql app starting ENTRYPOINT.

As example if you use wait-for-it.sh your ENTRYPOINT in your Dockerfile should change to following after copying above script to your project root:

ENTRYPOINT ["./wait-for-it.sh", "db:3306", "--", "java", "-jar", "app.jar"]

And two other important thing to consider here is:

  • Do not use links they are deprecated you should use user-defined network instead. All services in docker-compose file will be in single user-defined network if you don't explicitly define any network. So you just have to remove the links from compose file.
  • You don't need to publish the port for docker container if you only use it inside the user-defined network.
like image 140
Hansika Weerasena Avatar answered Sep 29 '22 15:09

Hansika Weerasena