😎다룰 내용
도커 컴포즈로 spring boot와 mysql을 연결하고 실행하는 과정을 알아본다.
연동에 있어 고려할 점
mysql 정보
도커 컴포즈를 활용해서 spring boot와 mysql을 연결하기 위해서는 mysql의 연결 url, IP, PORT, ID, Password 등을 알아야한다.
가상화 환경
Docker를 통한 가상화로 실행하려면 로컬에는 필요한 프로그램 설치가 없어도 괜찮다. 대신 이 경우에 고려할 점들이 있는데,
✅ spring 서버와 mysql 서버를 동일 네트워크로 묶어주는 것
✅ 데이터를 저장할 볼륨을 지정하는 것
✅ 두 서버를 연동하는 것
이에 대한 모식도는 아래와 같다.
이를 실행하기 위한 폴더에서 실습을 위한 아래의 깃 레퍼지토리 코드를 사용해서 진행한다.
https://github.com/codingspecialist/docker-study/tree/main/ex08
폴더 구조는 아래와 같다.
MySQL을 다룰 폴더 하나와 Springboot 서버를 다룰 폴더 그리고 각 폴더마다의 Dockerfile이 있고, 이것들에 대한 구성을 다룰 docker-compose.yml 파일이 있다.
Spring-boot 환경
먼저, spring-boot 서버 폴더에 대해서 살펴보자.
코드를 다루는 main의 자바 폴더를 제외한 나머지 폴더 구조는 위와 같다.
resources에 있는 파일마다 코드 먼저 살펴보자.
application-dev.yml
server:
servlet:
encoding:
charset: utf-8
force: true
port: 8080
spring:
datasource:
url: jdbc:h2:mem:test;MODE=MySQL
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
jpa:
open-in-view: false
hibernate:
ddl-auto: create
properties:
'[hibernate.default_batch_fetch_size]': 100
'[hibernate.format_sql]': true
show-sql: true
output:
ansi:
enabled: always
logging:
level:
'[com.example.server]': DEBUG
'[org.hibernate.type]': TRACE
application-prod.yml
server:
servlet:
encoding:
charset: utf-8
force: true
port: 8080
spring:
datasource:
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
driver-class-name: ${SPRING_DATASOURCE_DRIVER}
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
hibernate:
ddl-auto: none
show-sql: true
open-in-view: true
logging:
level:
'[com.example.server]': INFO
'[org.hibernate.type]': TRACE
application.yml
spring:
profiles:
active:
- dev
prod는 배포 환경, dev는 개발환경이다. 그리고 application.yml 파일은 Spring Boot 애플리케이션의 설정을 정의하는 파일로, 애플리케이션의 다양한 환경(예: 개발, 프로덕션)에서 사용할 수 있는 구성 옵션을 지정한다.
그리고 dockerfile의 스크립트를 살펴보자.
FROM openjdk:11-jdk-slim
WORKDIR /app
# COPY만 docker-compose 파일의 위치를 기반으로 작동함
COPY . .
# 개행문자 오류 해결 [unix와 window 시스템 차이]
RUN sed -i 's/\r$//' gradlew
# RUN은 현재 파일을 위치를 기반으로 작동함
RUN chmod +x ./gradlew
RUN ./gradlew clean build
ENV JAR_PATH=/app/build/libs
RUN mv ${JAR_PATH}/*.jar /app/app.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"]
Spring Boot 애플리케이션을 도커 컨테이너에서 실행하기 위해 작성된 것으로, 각 단계가 수행하는 작업은 다음과 같다.
FROM openjdk:11-jdk-slim
# openjdk:11-jdk-slim 이미지를 기반으로 지정
WORKDIR /app
# 작업 디렉토리 설정
COPY . .
# 현재 디렉토리(도커 컴포즈 파일이 있는 위치)의 모든 파일을 컨테이너의 /app 디렉토리로 복사
RUN sed -i 's/\r$//' gradlew
# Windows에서 작성된 gradlew 파일의 개행 문자를 Unix 스타일로 변환
RUN chmod +x ./gradlew
# gradlew 파일에 실행 권한을 부여
RUN ./gradlew clean build
# clean: 이전 빌드 결과를 삭제, build: 소스 코드를 컴파일하고, 테스트를 실행한 후, 최종적으로 JAR 파일을 생성
ENV JAR_PATH=/app/build/libs
RUN mv ${JAR_PATH}/*.jar /app/app.jar
# JAR_PATH라는 변수를 /app/build/libs로 설정
# mv(move) 명령어를 사용하여 JAR 파일을 다른 위치로 이동하는 작업
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"]
# java runtime을 호출하고 jar파일을 실행하며
# Spring Boot에서 사용할 프로파일을 설정하는 옵션을 prod로 설정
# 실행할 JAR 파일의 이름
위의 스크립트에서
RUN chmod +x ./gradlew 과 RUN mv ${JAR_PATH}/*.jar /app/app.jar이 이해되지 않아서 찾은 내용이다.
✅ RUN chmod +x ./gradlew
[Linux] 파일 권한과 쓰기 작업
이 글은 리눅스 시스템에서 파일 권한을 확인하고 변경하는 기본적인 방법과 파일 쓰기 작업에 대해 설명합니다. 실제 작업 환경에서는 이러한 명령어들을 사용할 때 주의가 필요하며, 보안을
velog.io
✅ RUN mv ${JAR_PATH}/*.jar /app/app.jar
먼저, 현재 WORKDIR /app 명령어에 의해 현재 작업 디렉토리가 /app으로 설정되었다.
그리고 RUN ./gradlew clean build 명령어를 실행하면, Gradle이 애플리케이션을 빌드한다.
이 과정에서 Gradle은 소스 코드를 컴파일하고, 테스트를 실행한 후, 최종적으로 JAR 파일을 생성한다. 생성된 JAR 파일은 일반적으로 build/libs 디렉토리에 저장되며, JAR 파일의 경로는 /app/build/libs가 된다. 여기서 /app은 작업 디렉토리이고, build/libs는 Gradle이 JAR 파일을 저장하는 기본 경로이다.
그리고 /app 경로 아래 해당 jar 파일을 app.jar의 이름으로 옮기는 것이다.
여기까지 springboot 서버 파일 구조와 dockerfile에 대한 스크립트이다.
MySQL 환경
이어서 db 서버 파일 구조와 dockerfile을 살펴보자.
dockerfile과 inti.sql파일을 만들었다.
먼저 dockerfile을 보자.
앞서 spring-boot에 비해서 비교적 간단하다.
FROM mysql:8.0
# MySQL 8.0 버전의 공식 도커 이미지를 기반으로 컨테이너를 생성
COPY init.sql /docker-entrypoint-initdb.d
# 현재 디렉토리에 있는 init.sql 파일을 도커 컨테이너의 /docker-entrypoint-initdb.d 디렉토리로 복사
ENV MYSQL_ROOT_PASSWORD=root1234
ENV MYSQL_DATABASE=metadb
ENV MYSQL_HOST=%
# 환경변수 설정
CMD ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
그리고 도커 컨테이너의 /docker-entrypoint-initdb.d 에 넣을 init.sql 파일을 만들었다.
CREATE TABLE user_tb (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
insert into user_tb(name) values ('John');
insert into user_tb(name) values ('Jahn');
이제 두 개의 dockerfile 기반 컨테이너를 조합할 compose 파일에 대한 스크립트를 살펴보자.
version: '3'
services:
db:
build:
context: ./docker-test-db
dockerfile: Dockerfile
ports:
- 3309:3306
volumes:
- ./docker-test-db/store:/var/lib/mysql
networks:
- network
# context: ./docker-test-db 디렉토리를 빌드 컨텍스트로 설정한다.
# dockerfile: 사용할 Dockerfile의 이름이며, context 경로의 도커 파일을 의미한다.
# ports: 3309:3306: 호스트의 3309 포트를 컨테이너의 3306 포트에 매핑
# volumes: 호스트의 ./docker-test-db/store 디렉토리를 컨테이너 내의 /var/lib/mysql 디렉토리에 마운트하여
# 데이터가 로컬의 해당 폴더에 영구적으로 저장된다.
# network: network: network라는 이름의 네트워크에 이 서비스를 연결
server:
build:
context: ./docker-test-server
dockerfile: Dockerfile
restart: always
ports:
- 8080:8080
depends_on:
- db
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/metadb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_DRIVER: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root1234
networks:
- network
# 위의 DB 설정과 비교하여 별도로 인식해야할 점은 restart: 과 depends_on: 그리고 environment: 에 해당한다.
# restart: 는 컨테이너가 중지되면 항상 재시작하도록 설정
# depends_on: 은 이 서비스가 시작되기 전에 db 서비스가 시작되도록 설정, 즉, Spring Boot 애플리케이션이 데이터베이스가 준비될 때까지 기다린다.
networks:
network:
여기서 각 서버의 필요한 설정과 달리 주의가 가는 부분은 두 컨테이너를 동일 네트워크로 잡는 것이다.
그 이유는 다음과 같은 것들을 고려할 수 있다.
(1) 컨테이너 간의 통신에 있어서 연결할 때, 동일 네트워크에 있으면, 서로의 이름으로 쉽게 통신이 가능하다.
(2) 도커는 동일 네트워크 내의 서비스 이름을 자동으로 DNS로 해석한다. 따라서, 다른 컨테이너에서 db라는 이름을 사용하면, 도커가 자동으로 해당 컨테이너의 IP 주소를 찾아 연결해준다.
(3) 동일 네트워크에 있는 컨테이너들만 서로 통신할 수 있기 때문에, 외부에서 접근할 수 없는 격리된 환경을 제공하기에 보안적인 강화가 이뤄진다.
(4) 여러 서비스를 하나의 네트워크에 묶어두면 관리가 용이해진다.
(5) 동일한 네트워크 내의 컨테이너 간 통신은 일반적으로 로컬 통신이므로, 외부 네트워크를 통한 통신보다 성능이 향상되기에 IO 발생에 의한 성능적 측면에서 유리하다.
지금까지 Spring-boot 과 MySql 을 사용하기 위한 dockerfile 및 dockercompose 내용들을 살펴보았다.
터미널에서 docker-compose up 명령어를 실행하고 controller 코드에 맞춰서 url을 입력하고 아래와 같이 브라우저에서 정상적으로 출력됨을 확인할 수 있었다.
init.sql을 통해 넣었던 데이터를 조회하는 url
'Docker > Docker 입문' 카테고리의 다른 글
도커 입문 22 - 도커 compose (Nginx ,React, Spring, Mysql 연동) - React학습 (1) | 2025.01.03 |
---|---|
도커 입문 21 - 도커 compose (Nginx ,React, Spring, Mysql 연동) - 시작 (0) | 2025.01.03 |
도커 입문 19 - 도커 compose 튜토리얼 따라하기(flask, redis, 캐시 삭제) (0) | 2024.12.30 |
도커 입문 18 - 도커 compose 시작 (0) | 2024.12.28 |
도커 입문 17 - 도커file ( mysql 환경 변수와 데이터 저장 ) (0) | 2024.12.27 |
댓글