Docker로 SpringBoot + MySQL DB 서버 연결을 실습해보겠습니다.
springBoot 프로젝트 - 로컬
MySQL - Docker 컨테이너
연동 성공
Dockerfile
FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/memo?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: root
password: 1234
jpa:
open-in-view: true
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
use-new-id-generator-mappings: false
show-sql: true
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
logging:
level:
org.hibernate.SQL: debug
💥 로컬내 docker 컨테이너로 돌리면 application, mysql 컨테이너 connection 문제로 실패
이유 불문...(23-01-10)
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
2차 시도 docker 같은 network로 설정?
--network springboot-mysql-net
실패 (2023-12-09)
하지만 aws ec2 인스턴스 에서 docker 컨테이너 실행시, 잘 실행됨!(23-01-12)
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://{aws ec2 pulbic ip}:3306/memo?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: root
password: 1234
network 연결 시도
--network springboot-mysql-net
Application Docker 컨테이너 실행
docker run \
--name=memo-test \
-p 8080:8080 \
-e TZ=Asia/Seoul \
-d \
mooh2jj/memo-test \
--restart unless-stopped \
--network springboot-mysql-net
MySQL Docker 컨테이너 실행
docker run \
--name mysql_8.0 \
-d \
--restart unless-stopped \
--network springboot-mysql-net \
-e MYSQL_ROOT_PASSWORD=1234 \
-e TZ=Asia/Seoul \
-p 3306:3306 \
-v //mysql//conf.d://etc//mysql//conf.d \
mysql:8.0.22 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
docker exec -it {mysql_8.0 컨테이너 id} bash
mysql -u root -p
# 1234
# database memo 만들기
$ create database memo;
$ show databases;
$ CREATE USER 'dsg'@'%' IDENTIFIED BY 'dsg1234';
$ GRANT ALL PRIVILEGES ON *.* TO 'dsg'@'%';
$ FLUSH PRIVILEGES;
docker-compose를 활용하여 한번에 컨테이너 정리가 가능합니다.
docker-compose.yml
version: '3'
services:
database:
container_name: mysql_db
image: mysql:8.0.22
restart: unless-stopped
environment:
# MYSQL_DATABASE: memo
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 1234
TZ: 'Asia/Seoul'
ports:
- "3306:3306"
volumes:
- ./mysql/conf.d:/etc/mysql/conf.d # MySQL 설정 파일 위치
- ./mysql/initdb.d/:/docker-entrypoint-initdb.d/ # 데이터베이스 초기화 sql
command:
- "mysqld"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- test_network
application:
container_name: memo-test
restart: on-failure
build:
context: ./
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql_db:3306/memo?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: "root"
SPRING_DATASOURCE_PASSWORD: "1234"
depends_on:
- database
networks:
- test_network
networks:
test_network:
./mysql/initdb.d/initdata.sql
DROP DATABASE IF EXISTS memo;
CREATE DATABASE memo;
USE memo;
application profile에 따라 정리
application.yml
spring:
profiles:
active: ${activeProfile:dev}
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
application-dev.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/memo?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: root
password: 1234
jpa:
open-in-view: true
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
use-new-id-generator-mappings: false
show-sql: true
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
logging:
level:
org.hibernate.SQL: debug
Dockerfile
FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-jar","/app.jar"]
DevInitData
초기화시, CommandLineRunner 상속으로 처리할 수 있음.
@Configuration
public class InitData {
@Bean
public CommandLineRunner initDevData(BlogService blogService) {
return args -> {
if(blogService.getBlogs().size() > 0) {
return;
}
blogService.create(new BlogCreateRequest("title1", "content1"));
blogService.create(new BlogCreateRequest("title2", "content2"));
};
}
}
결과
처음 데이타베이스 조정없이 확인가능한 것이 아주 좋다.