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 .
2
Answers
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 yourdocker-compose.yml
like this:In the
ports
section of MySQL container, you mention3307: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?