Run Mysql in a docker container with Spring Boot - mysql

I am trying to change my embedded in-memory H2 database to a MySQL instance using docker.
The application runs fine in-memory using docker, but I can't manage to change to MySQL.
I did some research, and managed to write this docker-compose.yml:
version: '3.3'
services:
#service 1: definition of mysql database
db:
image: mysql:latest
container_name: mysql-db2
environment:
- MYSQL_ROOT_PASSWORD=sa
- MYSQL_USER=password
ports:
- "3306:3306"
#service 2: definition of phpMyAdmin
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: my-php-myadmin
ports:
- "8082:80"
restart: always
depends_on:
- db
environment:
SPRING_DATASOURCE_USERNAME: sa
SPRING_DATASOURCE_PASSWORD: password
#service 3: definition of the spring-boot app
customerservice:
image: mysqldockerapp
container_name: mysql-docker-app
build:
context: .
dockerfile: Dockerfile
ports:
- "8084:8084"
depends_on:
- db
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db2:3306/customer?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: sa
SPRING_DATASOURCE_PASSWORD: password
And these are my application.properties
server.port=8084
spring.application.name=customer-service
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql-db2:3306/customer?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=never
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.org.hibernate.SQL=DEBUG
And my dockerfile
FROM openjdk:16-alpine3.13
MAINTAINER krzysztof.com
EXPOSE 8084
COPY target/myapp.jar myapp.jar
ENTRYPOINT ["java","-jar","/myapp.jar"]
The containers build correctly, but the app exits and I get:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
But the MySQL container is running, so I would appreciate any tips where should I look for possible reasons.

Related

Communication link failure. Docker-compose, Spring boot, MySQL

I'm having a problem in connection between my application to DB (in-spite of similarity)
Dockerfile:
FROM openjdk:8
ADD target/DockerMyBlog.jar DockerMyBlog.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "DockerMyBlog.jar"]
docker-compose.yml
version: "3"
services:
app-db:
image: mysql:latest
container_name: "my_db"
environment:
- MYSQL_ROOT_PASSWORD=hey
- MYSQL_DATABASE=javastudy
- MYSQL_USER=roman
- MYSQL_PASSWORD=hey
ports:
- 3306:3306
app:
build: .
container_name: "my_app"
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://app-db:3306/javastudy?autoReconnect=true&useSSL=false
depends_on:
- app-db
Instead of "build: ." tried "image: dockermyblog:latest". No result.
application.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javastudy
jdbc.username=roman
jdbc.password=hey
my_db is working. After "exec" I can create required tables in it. But can't launch my_app because of "Communication link failure".
What's wrong in my yml??
My guess is that 'localhost' is not a valid enpoint for a Docker container talking to another container running on the host in your application.properties. You can try and put it on IP address of the machine like so:
jdbc.url=jdbc:mysql://192.168.1.100:3306/javastudy
or
jdbc.url=jdbc:mysql://host.docker.internal:3306/javastudy

Docker database container does not get data in existing db

I have created a docker container for my existing local Mysql db. Although container creates tables in my local db correctly, the data in it is not passed at all and it returns an empty set constantly. Should I insert my data once again in container or is there a way to synchronize my local db and db in container? Here is the docker.complose.yml:
version: '3'
services:
mysql_st:
image: mysql:latest
container_name: mysql_st
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: components
MYSQL_PASSWORD: 123456
ports:
- "3308:3306"
app-mysql:
image: app-mysql:latest
container_name: app-mysql
ports:
- "9090:9090"
depends_on:
- mysql_st
volumes:
- ./target/app-mysql.jar:/app-mysql.jar
command: ["java", "-jar", "app-mysql.jar"]
build:
context: ./
dockerfile: Dockerfile
links:
- "mysql_st"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql_st:3306/components?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Dockerfile:
FROM openjdk:latest
ADD target/app-mysql.jar app-mysql.jar
EXPOSE 9090
ENTRYPOINT ["java","-jar","app-mysql.jar"]
VOLUME /var/lib/mysql
Application properties:
spring.datasource.username= root
spring.datasource.password= 123456
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.url=jdbc:mysql://mysql_st:3306/components?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
server.port = 9090
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
why a mysql docker container if you already have one mysql service on your local machine (host)?
I think the mysql service part should be removed from you composefile
and then you need to connect from the container (app-mysql) to the database running on the local machine
have a look at this:
From inside of a Docker container, how do I connect to the localhost of the machine?

Prisma 2 docker container can't connect MySQL Database container

I'm developing Backend server with prisma 2, MySQL, Docker-compose, GraphQL-Yoga server
My OS is Windows 10, docker compose use debian-openssl-1.1.x
problem is prisma 2 container can't connect MySQL container
docker-compose.yml
version: "3.7"
services:
mysql:
image: mysql:8.0.19
container_name: mysql
ports:
- 3306:3306
restart: always
environment:
MYSQL_DATABASE: $${MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: $${MYSQL_ROOT_PASSWORD}
volumes:
- /var/lib/mysql
prisma:
links:
- mysql
depends_on:
- mysql
container_name: prisma
ports:
- "5555:5555"
build:
context: back/prisma
dockerfile: Dockerfile
environment:
MYSQL_URL: $${MYSQL_URL}
MYSQL_ROOT_PASSWORD: $${MYSQL_ROOT_PASSWORD}
volumes:
- /app/prisma
backend:
links:
- mysql
depends_on:
- mysql
container_name: backend
ports:
- "4000:4000"
build:
context: back
dockerfile: Dockerfile
environment:
MYSQL_URL: $${MYSQL_URL}
FRONTEND_URL: $${FRONTEND_URL}
volumes:
- ./back:/app
- ./back/node_modules:/app/node_modules
- ./back/prisma:/app/prisma
frontend:
container_name: frontend
ports:
- "3000:3000"
build:
context: front
dockerfile: Dockerfile
environment:
BACKEND_URL: $${BACKEND_URL}
volumes:
- ./front:/app
- ./front/node_modules:/app/node_modules
.env
MYSQL_URL="mysql://root:prisma#mysql:3306/prisma"
BACKEND_URL=http://localhost:4000
FRONTEND_URL=http://localhost:3000
MYSQL_DATABASE:"prisma"
MYSQL_ROOT_PASSWORD:"prisma"
-schema.prisma
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
.env in prisma folder
DATABASE_URL="mysql://root:prisma#mysql:3306/prisma"
when i run docker-compose (docker-compose up), prisma container (prisma 2 studio) show this logs
Error in Prisma Client request:
Error:
Invalid `prisma.user.count()` invocation:
Authentication failed against database server at `mysql`, the provided database credentials for `root` are not valid.
Please make sure to provide valid database credentials for the database server at `mysql`.
at PrismaClientFetcher.request (/root/.cache/prisma/studio/app/runtime/index.js:1:52273)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
enter image description here
I think this error occurred because MySQL container has a password different from MYSQL_ROOT_PASSWORD which I wrote in the doctor-compose.yml.
But, i think there seems to be no problem with the setup, why is this error happening?
And if i did not set up MYSQL_ROOT_PASSWORD, what is the default password value generated by MySQL container?
I searched for days to find the answer to this problem, but I could not get the answer. please give me some advices. thank you

Spring Boot + MySQL + Docker Compose - Cannot make Spring Boot connect to MySQL

I've been trying to set up a connection between a backend (runs on Spring Boot) container and a pre-built MySQL container. However, I cannot get it to connect. My docker compose file is:
version: '3.7'
services:
test-mysql:
image: mysql
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
volumes:
db_data: {}
my application.properties:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.url=jdbc:mysql://test-mysql:3306/testdb?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=test
spring.datasource.password=test
When I use docker-compose up, Spring Boot is not able to recognize the container name test-mysql. It throws: java.net.UnknownHostException
When I change it to an IP, it says connection refused. I have been looking everywhere and couldn't come with a fix. I hope anyone can help me out. Thank you!
You have to mention the backend mysql properties in the composer file like below,
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://test-
mysql:3306/testdbautoReconnect=true&failOverReadOnly=false&maxReconnects=10
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
links:
- test-mysql:test-mysql
If this wouldn't work try to create a common docker network and add it to your composer file like below,
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://test-
mysql:3306/testdbautoReconnect=true&failOverReadOnly=false&maxReconnects=10
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
networks:
-common-network
test-mysql:
image: mysql
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
networks:
-common-network
#Docker Networks
networks:
common-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
You can define a common network on which both the application server and the database can connect. Please check the file (docker-compose.yml) below where I have defined a common network: backend
# Docker Compose file Reference (https://docs.docker.com/compose/compose-file/)
version: '3.7'
# Define services
services:
# App backend service
app-server:
# Configuration for building the docker image for the backend service
build:
context: . # Use an image built from the specified dockerfile in the `springboot-app-server` directory.
dockerfile: Dockerfile
ports:
- "8080:8080" # Forward the exposed port 4000 on the container to port 4000 on the host machine
restart: always
depends_on:
- db # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://test-mysql:3306/testdb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
networks: # Networks to join (Services on the same network can communicate with each other using their name)
- backend
# Database Service (Mysql)
db:
image: mysql:5.7
ports:
- "3306:3306"
restart: always
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
volumes:
- db-data:/var/lib/mysql
networks:
- backend
# Volumes
volumes:
db-data:
# Networks to be created to facilitate communication between containers
networks:
backend:
I have written a blog and a simple working Spring Boot MySQL application on GitHub which tells about using Docker Compose. Please check: http://softwaredevelopercentral.blogspot.com/2020/10/spring-boot-mysql-docker-compose-example.html
If you would like to use this test-mysql in your spring config
spring.datasource.url=jdbc:mysql://test-mysql:3306/testdb?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
Then add the hostname attribute at service test-mysql
version: '3.7'
services:
test-mysql:
image: mysql
hostname: test-mysql
...
I hope this has been already solved but in case it hasn't yet, the problem lies in mysql docker container lagging behind the start up.
Another problem is that you might need to build the jar file and then copy it the container. That's a big problem because when you build the jar file, the database with db as hostname is unavailable. So when you are building the jar file, skip the test.
This is bash script i created but you can run command one by one:
#!/bin/bash
cd storage-service
rm -rf target/
mvn clean compile package -Dmaven.test.skip=true
cd ..
docker-compose up
In case you want to initialize db in the container. That file is in the folder env where i have a file database.env
-- create the databases
CREATE DATABASE IF NOT EXISTS model_storage;
-- create the users for each database
CREATE USER 'arsene'#'localhost' IDENTIFIED BY 'arsene';
GRANT CREATE, ALTER, INDEX, LOCK TABLES, REFERENCES, UPDATE, DELETE, DROP, SELECT, INSERT ON `model_storage`.* TO 'arsene'#'localhost';
FLUSH PRIVILEGES;
The backend service Dockerfile looks like this:
FROM adoptopenjdk/openjdk11
COPY target/*.jar storage.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /storage.jar" ]
EXPOSE 8089
The database env file looks like this:
MYSQL_ROOT_PASSWORD=arsene
MYSQL_DATABASE=model_storage
MYSQL_USER=arsene
MYSQL_PASSWORD=arsene
DATABASE_HOST=model_storage
DATABASE_USER=arsene
DATABASE_PASSWORD=arsene
DATABASE_NAME=model_storage
DATABASE_PORT=3306
In case you intend to pass JAVA_OPTS env in the image. These can be used later as seen in docker-compose.yml below
Your backend (the service that depends on the mysql db) needs to restart until the docker-compose is able to resolve the the container name of mysql, in my case its name is db. And don't forget to include datasource connection properties in docker-compose backend service image as i did below. I am not an expert in spring boot and neither in docker but for now it works!
Below is the way mine is structured:
I am using docker version: "3.8"
Storage service
storage-service:
container_name: storage-service
restart: always
build:
context: storage-service
image: "service_storage_image"
depends_on:
- db
ports:
- "8089:8089"
links:
- db
env_file:
- env/database.env
environment:
WAIT_HOSTS: db:3306
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/model_storage?allowPublicKeyRetrieval=true&useSSL=false
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: arsene
healthcheck:
test: "/usr/bin/mysql --user=arsene --password=arsene--execute \"SHOW DATABASES;\""
interval: 2s
timeout: 20s
retries: 10
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://eureka-registry-server:7070/eureka
-DZIPKIN_SERVER=http://zipkin:9411/
networks:
- private-network-mms
My db in docker-compose is structured this way:
Mysql database
db:
hostname: db
container_name: db
image: "mysql:latest"
env_file:
- env/database.env
volumes:
- type: bind
source: ./env/setup.sql
target: /docker-entrypoint-initdb.d/setup.sql
- db_volume:/var/lib/mysql
ports:
- 3307:3306
networks:
- private-network-mms

docker compose: spring boot connection to mysql database refused

I'm pretty new to Docker and I need to startup my Angular/SpringBoot/MySQL project with docker-compose on the docker toolbox. I copied a docker yml file into my project which used the same technologies and changed the paths inside of it to match my project. However when I try docker-compose, it throws the following error:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
[...] 84 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
the docker-compose.yml looks like:
version: '3'
services:
database:
image: mysql
container_name: database
environment:
MYSQL_ROOT_PASSWORD: ****
MYSQL_DATABASE: db_example
MYSQL_USER: springuser
MYSQL_PASSWORD: ****
ports:
- 3306:3306
volumes:
- db_exampleData:/var/lib/mysql
springapi:
image: openjdk:10-jre-slim
container_name: springapi
ports:
- 8443:8443
depends_on:
- database
volumes:
- ./backend/target/backend-0.1.0.jar:/application.jar
command: ["java", "-jar", "application.jar"]
angular:
image: nginx:alpine
container_name: angular
ports:
- 4200:80
depends_on:
- springapi
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./frontend/my-app/dist/my-app:/usr/share/nginx/html
volumes:
db_exampleData:
the application.properties:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=false
spring.datasource.url=jdbc:mysql://localhost:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=****
server.port=8443
any suggestion would be helpful!
you need to change your connecion like this:
jdbc:mysql://database:3306/db_example
and add this to your docker-compose under springapi service:
links:
- database
on the other hand you may use wait-for-it.sh to check if DB is up by add a command section under springapi service:
command: ["path/to/wait-for-it.sh", "database:3306", "-t", "6000", "--", "YOUR ACTUAL COMMAND"]