Spring boot + MySQL. Docker - mysql

I`m create simple app on spring boot + MySQL. On local pc it works correctly, but when i package it in docker, i catch some errors: container with DB works well, i can connect to it via workbanch, the container with the application crashes on startup with an error:
"java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
...
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
...
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
Caused by: java.net.ConnectException: Connection refused
..."
My Dockerfile:
FROM openjdk:17-alpine
ADD /target/tests-0.0.1-SNAPSHOT.jar backend.jar
ENTRYPOINT ["java", "-jar", "backend.jar"]
My docker-compose.yml:
version: '3'
services:
personsdb:
image: 'mysql:8.0.31'
container_name: 'persons-db'
environment:
- 'MYSQL_ROOT_PASSWORD=Qwer'
- 'MYSQL_DATABASE=persons'
- 'MYSQL_USER=mysql'
- 'MYSQL_PASSWORD=Qwer'
ports:
- '3305:3306'
app:
container_name: 'persons-app'
ports:
- 8088:8080
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://personsdb:3305/persons?autoReconnect=true&useSSL=false
depends_on:
- 'personsdb'
build: ./
My application.properties:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://personsdb:3305/persons
spring.datasource.username=root
spring.datasource.password=Qwer
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
I tried to
run: docker-compose down --rmi all
rename service
upgrade MySQL Connector
add more dependences to pom.xml
...

It seems you have to create a bridge to let them communicate.
Please check the link below
https://www.tutorialworks.com/container-networking/
when they are in the same host, below configuration also worked for me.
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://host.docker.internal:5432/DB-NAME

Related

Problem with dockercompose connection to MySQL container

I'm having trouble connecting my spring application with the MySQL database.
In particular, I report the code of the docker compose, the docker file, application.yml and the error log.
docker-compose:
version: '3.3'
services:
my-sql-db:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=user
- MYSQL_USER=user
- MYSQL_DATABASE=spring-app
ports:
- "3306:3306"
customerservice:
image: customer-service
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
depends_on:
- my-sql-db
environment:
SPRING_PROFILES_ACTIVE: MySQLdocker
Dockerfile:
FROM maven:3.6.3-jdk-8
COPY ./ ./
RUN mvn clean package
EXPOSE 8080
CMD ["java", "-jar", "target/my-spring-project-0.0.1-SNAPSHOT.jar"]
Application.yml:
spring:
jpa:
open-in-view: false #per levare warnig OpenSessionInView
properties:
hibernate:
jdbc:
time_zone: CET
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: none
datasource:
url: jdbc:mysql://my-sql-db:3306/spring-app?createDatabaseIfNotExist=true
username: user
password: user
config:
activate:
on-profile: MySQLdocker
Executing the command "docker-compose up -d" the output error is:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
I'm not seeing MYSQL_PASSWORD defined in your docker-compose file.
Generally, the error suggests the app cannot connect to MySQL at all. When you have such a problem that could be caused by many things, you should try and narrow it down. Check if the DB is up and running. If yes, then try to connect to it from some MySQL client. And so on, until you figure out what exactly went wrong or at least come up with a more specific question.

Docker, Spring, Mysql java.net.ConnectException: Connection refused (Connection refused) while trying to run docker app

I have a Springboot application which connects to MySQL database. When I try to run the application it gives following exceptions :
- com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
- The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
- java.net.ConnectException: Connection refused (Connection refused)
My Dockerfile is this :
FROM openjdk:8
ADD target/studyapp.jar studyapp.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "studyapp.jar"]
My application.properties :
spring.datasource.url=jdbc:mysql://localhost:3306/study # ${MYSQL_HOST:localhost}
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=false
spring.jpa.database=mysql
spring.hibernate.dialect=org.hibernate.dialect.MySQLDialect
security.basic.enable: false
security.ignored=/**
This is the command that I used for running mysql container :
sudo docker run --net studyapp-network --name localhost -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=study -e MYSQL_USER=cnyt -e MYSQL_PASSWORD=root -d mysql:5.7.32
And this is for running the app container :
sudo docker run --net studyapp-network -p 8080:8080 cuneytyvz/studyapp
I'm using 'localhost' as name for my mysql container. I tried to change this, same error occured.
I also can run this app using docker-compose with no problem. But I want to see it working without docker-compose also. What might be the problem?
This is the working docker-compose file :
version: '3.3'
services:
#service 1: definition of mysql database
mysql-db:
image: mysql:latest
container_name: mysql-db
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=cnyt
ports:
- "3306:3306"
restart: always
volumes:
- my-datavolume:/var/lib/mysql
#service 2: definition of phpMyAdmin
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: my-php-myadmin
ports:
- "8082:80"
restart: always
depends_on:
- mysql-db
environment:
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
#service 3: definition of your spring-boot app
studyapp: #it is just a name, which will be used only in this file.
image: studyapp #name of the image after dockerfile executes
container_name: studyapp #name of the container created from docker image
build:
context: . #docker file path (. means root directory)
dockerfile: Dockerfile #docker file name
ports:
- "8080:8080" #docker containter port with your os port
restart: always
depends_on: #define dependencies of this app
- mysql-db #dependency name (which is defined with this name 'db' in this file earlier)
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/study?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
volumes:
my-datavolume:
It's because I was using 'localhost' as name for my mysql container. It probable confuses my application docker container. I changed it and it works correctly.

Spring boot JDBC can't connect to mysql in docker container

I'm trying to run a spring boot app (as a simple REST api) and mysql server in two separate docker containers. But, I can't get the jdbc connection in the spring app to connect to mysql. They are both working independently and the implementation works when I run spring boot and mysql locally.
docker-compose.yml
version: '3'
services:
database:
image: mysql:latest
container_name: mysqldb
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
- MYSQL_ROOT_PASSWORD=password
expose:
- 3306
ports:
- 3306:3306
networks:
- backend
volumes:
- "dbdata:/var/lib/mysql"
web:
container_name: springboot
build: .
depends_on:
- database
expose:
- 8080
ports:
- 8080:8080
networks:
- backend
networks:
backend:
volumes:
dbdata:
In the spring boot app:
val dataSource = DriverManagerDataSource()
dataSource.setDriverClassName("com.mysql.jdbc.Driver")
dataSource.setUrl("jdbc:mysql://mysqldb:3306/$dbName?characterEncoding=latin1")
dataSource.username = "dev"
dataSource.password = "password"
val jdbcTemplate = JdbcTemplate(dataSource)
Error returned from spring boot:
{
"status": 500,
"error": "Internal Server Error",
"message": "Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure\n\nThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server."
}
I AM able to connect to the mysql container from the spring boot container via the mysql cli. So, it appears the springboot container is able to resolve "mysqldb."
This seems like it should be pretty simple. I'm not sure where the error lies but I would guess it has something to do with spring boots inner workings that I am unfamiliar with.
change this dataSource.setUrl("jdbc:mysql://mysqldb:3306/$dbName") , to:
dataSource.setUrl("jdbc:mysql://database:3306/$dbName")
your service name in compose is database, so you need to use it

Can't connect a spring-boot 2 service to mysql in a different container

I have a spring-boot 2.16 service that connects to a my-sql data base. It works as expected as far as all the components are on the same host. I tried to improve the solution and to have a docker container running the sprin-boot service with Tomcat embedded and another docker container running the my-sql server.
The same code doesn't work any more. here is the exception:
2019-06-28 12:23:48 ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:988)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:341)
....
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:211)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:300)
... 66 common frames omitted
So, it's like the my-sql server IP address is not found or the server is not running, etc.
Here is the docker-compse.yml file:
version: "2"
services:
rdf-data:
container_name: rdf-data
image: mysql:latest
environment:
MYSQL_DATABASE: test
MYSQL_USER: nicolas
MYSQL_PASSWORD: mysql
MYSQL_ROOT_PASSWORD: mysql
ports:
- 3306:3306
- 33060:33060
hostname: rdf-data
networks:
net1:
ipv4_address: 192.19.0.4
rdf-core:
image: openjdk:8-jdk-alpine
depends_on:
- rdf-data
container_name: rdf-core
links:
- rdf-data:rdf-data
volumes:
- ../docker:/usr/local/share/rdf
ports:
- "8080:8080"
entrypoint: /usr/local/share/rdf/run.sh
hostname: rdf-core
environment:
PROFILE: "default"
SERVER_PORT: "8080"
networks:
net1:
ipv4_address: 192.19.0.8
networks:
net1:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 192.19.0.0/24
gateway: 192.19.0.1
Here there are two containers: rfd-core having the IP address of 192.19.0.8 and rdf-data having the IP address 192.19.0.4. Each container is able to ping the other. The hst machine is able to ping each container. From the host machine I'm able to correctly connect to the my-sql server running on rfd-data using the my-sql command line client.
However, my service connection shown here below doesn't work:
database=mysql
spring.datasource.url=jdbc:mysql://192.19.0.4/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=mysql
spring.datasource.driver-class=com.mysql.cj.jdbc.MysqlXADataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
...
Is there anything I'm missing?
Try specifying the parameters of the spring boot app in the environment part of your docker-compose file :
rdf-core:
image: openjdk:8-jdk-alpine
depends_on:
- rdf-data
container_name: rdf-core
links:
- rdf-data:rdf-data
volumes:
- ../docker:/usr/local/share/rdf
ports:
- "8080:8080"
entrypoint: /usr/local/share/rdf/run.sh
hostname: rdf-core
environment:
PROFILE: "default"
SERVER_PORT: "8080"
spring.datasource.url=jdbc:mysql://ipaddress/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=mysql
spring.datasource.driver-class=com.mysql.cj.jdbc.MysqlXADataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
Another possible cause of the problem : the depends_on doesn't guarantee that the dependency container is fully running. so if the MySQL containers takes more time to fully start than the Spring Boot container, the connection fails.
Take a look at this:
Spring Boot + docker-compose + MySQL: Connection refused
There are few possible ways to make a container wait for another:
Use the restart on failure feature, or docker compose wait (
Github link )

SpringBoot on Docker unable to connect to MySQL

I have written docker compose for my SpringBoot app with MySQL. When I run docker-compose up eventually I get an error:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:325) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
... 69 common frames omitted
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:172) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:444) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
at java.sql.DriverManager.getConnection(DriverManager.java:664) ~[na:1.8.0_111]
at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[na:1.8.0_111]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:153) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:144) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:196) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:159) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
... 70 common frames omitted
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
At first I thought the the cause was the db but I managed to run local instance of the app and connect to the docker mysql.
Next I assumed that the spring app tries to connect to mysql before it is up and running but I restarted the app (mysql was already running) and got the same error.
Currently I think that this might be caused by the windows10 firewall but I am running low on ideas.
Dockerfile:
FROM java:8
LABEL maintainer="maciej"
WORKDIR /app
COPY target/kamienica.jar /app/kamienica.jar
ENTRYPOINT ["java", "-jar","kamienica.jar", "--spring.profiles.active=docker"]
docker-compose.yml
version: '3'
services:
mysql-docker-container:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=maciej
- MYSQL_DATABASE=kamienica
- MYSQL_USER=maciej
- MYSQL_PASSWORD=maciej
volumes:
- /data/mysql
ports:
- 3333:3306
container_name: kamienica-db
kamienica-app:
image: kamienica-image
build:
context: ./
dockerfile: Dockerfile
depends_on:
- mysql-docker-container
ports:
- 8080:8080
volumes:
- /data/spring-boot-app
container_name: kamienica-app
and the application-docker.properties:
jdbc.url = jdbc:mysql://kamienica-db:3333/kamienica?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
jdbc.username = maciej
jdbc.password = maciej
hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.current_session_context_class=thread
hibernate.connection.characterEncoding=UTF-8
hibernate.connection.charSet=UTF-8
Try to change the url into this your properties file
jdbc:mysql://mysql-docker-container:3306/kamienica
jdbc:mysql://[mysql-docker-container-name]:[mysql-port]/[db-name]
in your docker-compose.yml mysql-docker-container-name is mysql-docker-container
so change your spring boot application.properties file mysql url as following
jdbc:mysql://mysql-docker-container:3306/kamienica