I have a simple Java application using a mysql.
This is my docker-compose.yaml:
version: '2.1'
services:
docker-mysql:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=test2
- MYSQL_PASSWORD=root
ports:
- 3306:3306
my-app:
image: 0935a6b56fe5
depends_on:
- docker-mysql
ports:
- 8080:8080
environment:
- DATABASE_HOST=docker-mysql
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=test2
- DATABASE_PORT=3306
Image with id 0935a6b56fe5 is a mysql image.
And this is my application.properties:
## Server config
server.port=8080
server.tomcat.uri-encoding=utf-8
## MYSQL JPA
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.datasource.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validationQuery=SELECT 1
#Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driverClassName=com.mysql.jdbc.Driver
When i try docker-compose up application tries to run but it gives me a Connection Refused error.
What is wrong with this?
Most likely this line
spring.datasource.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8
should read
spring.datasource.url=jdbc:mysql://docker-mysql:3306/test2?characterEncoding=utf8
because your my-app is running inside of the docker container and localhost is not what you think it is. You can access other docker containers inside of docker-compose with the name of the service you have chosen inside your docker-compose.yml.
Your spring.datasource.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8 refers to localhost. Can you try spring.datasource.url=jdbc:mysql://docker-mysql:3306/test2?characterEncoding=utf8
Also the spring.datasource.password= is blank. How do you provide the password?
Related
I'm stuck with SQLNonTransientConnectionException in Spring Boot application with MariaDB database using docker.
Docker-compose.yaml
version: '3.1'
services:
stats-server:
container_name: stats-server
build:
dockerfile: Dockerfile-statsserver
context: ./stats-server
ports:
- "9090:9090"
depends_on:
- stats-db
stats-db:
container_name: stats-db
image: mariadb
ports:
- "9091:3306"
environment:
- MARIADB_ROOT_PASSWORD=root
- MARIADB_DATABASE=stats
- MARIADB_USER=stats_user
- MARIADB_PASSWORD=stats_password
application.properties
#port
server.port=9090
#MariaDB
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://stats-db:9091/stats
spring.datasource.username=stats_user
spring.datasource.password=stats_password
spring.jpa.hibernate.ddl-auto=update
After docker-compose up command I've got the SQLNonTransientConnectionException error:
java.sql.SQLNonTransientConnectionException: Socket fail to connect to host:address=(host=stats-db)(port=9091)(type=primary). Connection refused
Database container runs well.
With Intellij Idea I can connect by this url:
jdbc:mariadb://localhost:9091/stats
my bad, should been use internal container port
spring.datasource.url=jdbc:mariadb://stats-db:3306/stats
I have created a docker-compose.yml to run a postgresql database . While the image is pulled and can run succesfully I am unable to connect to my database through a spring boot project I have . When I try to run my spring boot project after succesfully running my postgresql container with docker-compose up I get the error org.postgresql.util.PSQLException: The connection attempt failed. and a huge text of error logs underneath where I spotted the cause.
Caused by: java.net.UnknownHostException: postgresqldb
which is the name of my db image .
My docker-compose.yml at the root of my spring project
version: '3.1'
services:
postgresqldb:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=booksdb
My application.properties in my spring boot project .
server.port=8081
server.servlet.context-path=/rest
#Postgres
spring.datasource.url=jdbc:postgresql://postgresqldb:5432/booksdb
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
#JWT
jwt.secret-key=someKey
I would appreciate your help .
Maybe you should add a hostname to the container:
version: '3.1'
services:
postgresqldb:
image: postgres
hostname: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=booksdb
docker uses its own network and resolves hostname internally. You should assign a hostname to the running container that may be found for the rest of the containers.
Problem Description
Spring Boot(app) container cant connect to "mysql" container
Problem Output
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
application.properties
spring.datasource.username = root
spring.datasource.url = jdbc:mysql://mysql:3306/fms?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
spring.datasource.password = manager#123
docker-compose.yml
version: '3.7'
services:
mysql:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
ports:
- "33061:3306"
networks:
- spring-boot-mysql-network
environment:
MYSQL_DATABASE: fms
MYSQL_ROOT_PASSWORD: manager#123
volumes:
- ./database_storage:/docker-entrypoint-initdb.d
app:
build:
context: .
dockerfile: app.Dockerfile
ports:
- "8091:8080"
networks:
- spring-boot-mysql-network
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
restart: always
depends_on:
- mysql
environment:
PMA_HOST: database
PMA_PORT: 3306
ports:
- "9091:80"
networks:
spring-boot-mysql-network:
driver: bridge
I had done a silly mistake.
I was updating my application.property file and docker-compose up
--build.But I never repackaged war file.So I was reading my old war file and thus reading my old property file
Your settings look correct to me. However, you are using the latest docker image of MySQL (which is 8.0.x at the time of writing). So, the exception you got indicates that there is a compatibility issue between your MySQL connector and MySQL server version. Which version of MySQL Connector/J are you using in your Spring Boot application? You need to update the connector or downgrade the MySQL docker image version.
Could you try updating mysql connector version to mysql-connector-java-8.0.11
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"]
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.
I was facing the same issue and in case you do not want to use any custom scripts, this can easily be resolved using health checks along with depends on. A sample using these is as follows:
services:
mysql-db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=vikas1234
- MYSQL_USER=vikas
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
app:
image: shop-keeper
container_name: shop-keeper-app
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
mysql-db:
condition: service_healthy
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/shopkeeper?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: vikas1234
Your config looks nice, I would just recommend:
Remove links: db. It has no value in user-defined bridge networking
Remove port exposing for db unless you want to connect from outside docker-compose - all ports are exposed automatically inside user-defined bridge network.
I think the problem is that database container takes more time to start than web. depends_on just controls the order, but does not guarantee you database readiness. If possible, set several connection attempts or put socket-wait procedure in your web container.
I have a docker compose for MySQL + Spring boot app:
This is how my docker-compose.yaml looks like
version: "3.3"
services:
docker-mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 'pass'
MYSQL_DATABASE: 'test'
volumes:
- /var/lib/mysql
ports:
- 3306:3306
my-app:
build: .
depends_on:
- docker-mysql
ports:
- 8080:8080
restart: on-failure
And this is my Dockerfile:
FROM openjdk:8
EXPOSE 8080
ADD /target/app-0.0.1.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
This is the application.properties of my app:
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.datasource.url=jdbc:mysql://docker-mysql:3306/test?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driverClassName=com.mysql.jdbc.Driver
But when i run the containers with docker-compose up application encounter with access denied:
Access denied for user 'root'#'172.20.0.3' (using password: NO)
In the log file, mysql created with an empty password!
[Warning] root#localhost is created with an empty password !
you following properties should be changed to use the user and pass, you defined in docker-mysql.
spring.datasource.password=pass
Also, add the links option in your spring-boot app.
depends_on:
- docker-mysql
links:
- docker-mysql
I don't think it matters, but the examples on the documentation uses the password without quotes. If above fails, try that as well.
You need mysql access with user root , so Run below command with mysql root user :
GRANT ALL PRIVILEGES ON *.* TO 'root'#'172.20.0.3'
IDENTIFIED BY 'pass'
WITH GRANT OPTION;
FLUSH PRIVILEGES;
Please check!