0

My project is a combination of Mysql, Spring Boot and Docker but when I try to dockerize it I am facing with an error. I searched for it but couldn't find any solution. Here is my Dockerfile :

FROM maven:3.8.3-openjdk-17 AS build

WORKDIR /app
COPY target/TicketApp2-0.0.1-SNAPSHOT.jar /app
EXPOSE 8080

CMD ["java", "-jar", "TicketApp2-0.0.1-SNAPSHOT.jar"]

docker-compose.yml :

version: "3"
services:
  mysqldb:
    container_name: mysqldb
    image: mysql
    ports:
      - "3307:3306"
    environment:
      MYSQL_DATABASE: book
      MYSQL_ROOT_PASSWORD: 1234
      MYSQL_PASSWORD: 1234
    networks:
      common_network:
        aliases:
          - db


  springboot-app:
    container_name: spring-app
    image: springboot-app
    build: .
    ports:
      - "8080:8080"
    environment:
      MYSQL_HOST: mysqldb
      MYSQL_USER: root
      MYSQL_PASSWORD: 1234
      MYSQL_PORT: 3306    # we are in same network so we connect internally.
    depends_on:
      - mysqldb
    networks:
      - common_network

networks:
  common_network:
    driver: bridge

The error :

spring-app  | 2023-06-20 10:26:14.454  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
spring-app  | 2023-06-20 10:26:15.708 ERROR 1 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.
spring-app  | 
spring-app  | com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
spring-app  | 
spring-app  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
spring-app  |   at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:824) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:444) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar!/:na]
spring-app  |   at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494) ~[hibernate-core-5.6.5.Final.jar!/:5.6.5.Final]
spring-app  |   at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.16.jar!/:5.3.16]
spring-app  |   at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.4.jar!/:2.6.4]
spring-app  |   at com.yunus.ticketapp2.TicketApp2Application.main(TicketApp2Application.java:11) ~[classes!/:0.0.1-SNAPSHOT]
spring-app  |   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
spring-app  |   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
spring-app  |   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
spring-app  |   at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
spring-app  |   at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[TicketApp2-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
spring-app  |   at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[TicketApp2-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
spring-app  |   at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[TicketApp2-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
spring-app  |   at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[TicketApp2-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
spring-app  | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
spring-app  | 
spring-app  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
spring-app  |   at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
spring-app  |   at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
spring-app  |   at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
spring-app  |   at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
spring-app  |   at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]
spring-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.NativeSession.connect(NativeSession.java:120) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:944) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:814) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   ... 57 common frames omitted
spring-app  | Caused by: java.net.ConnectException: Connection refused
spring-app  |   at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
spring-app  |   at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
spring-app  |   at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
spring-app  |   at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
spring-app  |   at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
spring-app  |   at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
spring-app  |   at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-j-8.0.32.jar!/:8.0.32]
spring-app  |   ... 60 common frames omitted

Briefly here I get some information from MySQL database and sending them to my local website. Thank you in advance.

EDIT : I can access MySQL container with my Spring Boot application externally with jdbc:mysql://localhost:3307/book .

3 Answers3

0

The error is probably caused by a common issue with MySQL in docker-compose that the database is not ready to accept connections yet, even after the conditions of your depends_on are fulfilled (which checks for the container to be up and running, but not for the initialization to be finished).

There are multiple solutions to this issue. Usually some form of "wait-for-it" script or similar that pings the database until it is ready. See some of these options discussed here: Docker-compose check if mysql connection is ready

Edit: Also, since your mysqldb service definition does not include a volume, the database will be reinitialized with each restart of the container. You could define a volume for the MySQL data in your docker-compose.yml like this:

mysqldb:
...
    volumes:
      - /var/lib/mysql
Rob
  • 491
  • 4
  • 14
  • I checked this post. It was useful thanks to it I could run my spring boot container but some time later it again being down. The problem here I face is application can't connect to mysql database. Do I need to create a network for them? But as I know they automatically link to a same default network. – Yunus Emrah Uluçay Jun 20 '23 at 11:25
  • Did you restart the docker-compose in the meantime? I see that your `mysqldb` service does not have a volume, so its data is not persisted between restarts, which means that this problem will reoccur with each restart. You could add a volume to your mysql service definition. I will edit my answer. – Rob Jun 20 '23 at 12:35
  • It wasn't the cause of the problem. – Yunus Emrah Uluçay Jun 21 '23 at 07:03
0

In the ports section of MySQL container, you mention 3307:3306. This means that port 3306 of the container will bind with port 3307 of the host machine. When you later connect your application with this MySQL container, you are trying to connect to port 3306 of the host machine. Can you change that to 3307 and try again?

Neha P
  • 13
  • 7
0

This is my application.properties :

spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/book
server.error.whitelabel.enabled=false
spring.datasource.username=${MYSQL_USER:root}
spring.datasource.password=${MYSQL_PASSWORD:1234}
spring.jpa.open-in-view=false
spring.thymeleaf.cache=false
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

Actually this was the correct but before change this I created the .jar file. So in .jar file I had the old application.properties informations. Don't forget to update your .jar file :)

EDIT: By the way here I use 3306 because my Spring Boot container and MySQL container are in same network so it uses internal port rather than 3307 (external one). And last thing use org.hibernate.dialect.MySQL8Dialect rather than MySQLDialect depending on your MySQL version. Here for example I have 8+