본문 바로가기
DevOps/Docker

[Docker] docker compose로 Spring + MySQL 배포 환경 만들기

by 방배킹 2024. 2. 22.

docker compose를 통해 하나의 네트워크에 Spring, MySQL 컨테이너를 띄워서 실행시켜보자

 

일단 spring, mysql의 Dockerfile을 작성하고 docker-compose.yml을 작성해 spring과 mysql을 도커로 띄워서 실행시켜 보았다.

 

코드는 얼마전 스프링 시큐리티 실습을 할때 사용했던 프로젝트를 사용했다.

 

이 과정에서 몇가지 오류가 발생했고 이를 정리하고자 한다.

 

1. ./gradlew clean build 오류 - (1)

2. ./gradlew clean build 오류 - (2)

3. 3306 포트 사용중으로 인한 오류

4. db폴더에 있는 store 폴더에 의한 오류

 

1. ./gradlew clean build 오류 - (1)

RUN ./gradlew clean build

./gradlew clean build 시에 오류가 발생했었는 unix와 window 시스템의 차이로 인해 발생하는 오류로 

# 개행문자 오류 해결 [unix와 window 시스템 차이]
RUN sed -i 's/\r$//' gradlew

해당 코드를 추가해주면 해결할 수 있다.

 

2. ./gradlew clean build 오류 - (2)

# 개행문자 오류 해결 [unix와 window 시스템 차이]
RUN sed -i 's/\r$//' gradlew

위 코드를 추가 해주었는데도 오류가 발생했다.

 

테스트가 실패 오류가 발생했고 이유를 찾아보았는데 정확히 찾아내지 못하여서

일단 -x test를 통해 빌드시 test를 하지 않고 넘아가도록 설정했다.

3. 3306 포트 사용중으로 인한 오류

이후 다시 실행을 했는데  

다음과 같이 3306 포트가 사용중이라는 오류가 발생하였고 이를 해결하기 위해 3307 포트로 포트포워딩을 통해  해결하였다.

ports:
  - 3307:3306

 

주의

environment:
  SPRING_DATASOURCE_URL: jdbc:mysql://my-database:3306/spring-test-db
environment:
  SPRING_DATASOURCE_URL: jdbc:mysql://my-database:3307/spring-test-db

 

포트 포워딩 3307:3306으로 진행했는데

 

그러면 데이터베이스 접속 url의 포트는 3306일까 3307일까?

 

3307:3306이 의미 하는것이 host의 3307 포트를 docker의 3306 포트로 연결하는것이다.

따라서 local에서 접속을 할때는 3307로 접속을하면 docker의 3306 mysql로 접속이되고

environment:
  SPRING_DATASOURCE_URL: jdbc:mysql://my-database:3306

docker-compose.yml에서 spring 서버가 mysql에 접속할때는

docker 내부에서 같은 네트워크에서 접속하는것이므로 3306 포트를 사용한다.

 

4. db폴더에 있는 store 폴더에 의한 오류

포트포워딩을 해준뒤 생성된 컨테이너를 지우고 다시 실행시켰는데 또 오류가 발생하였다.

docker-compose.yml 파일에서 볼륨 설정을 해주었는데

volumes:
  - ./docker-test-db/store:/var/lib/mysql

 

해당 설정으로 인해 생긴 파일을 지워지지 않아서 오류가 발생하것이였고

해당 파일을 지운뒤 다시 실행시켰더니 컨테이너가 잘 생성되었고 실행, 접속 모두 잘 되었다.

 

코드

최종 코드는 다음과 같다.

// build.gradle
// dockerfile에서 빌드를 하면 jar 파일이 2개 생기는데 1개만 생기도록 설정
jar {
    enabled = false
}​

 

# Dockerfile
# C:\springstudy\Dockerfile

FROM openjdk:17-jdk-slim

WORKDIR /app

# COPY만 docker-compose 파일의 위치를 기반으로 작동함
COPY . .

# 개행문자 오류 해결 [unix와 window 시스템 차이]
RUN sed -i 's/\r$//' gradlew

# RUN은 현재 파일을 위치를 기반으로 작동함
RUN chmod +x ./gradlew
# -x test 추가
RUN ./gradlew clean build -x test

ENV JAR_PATH=/app/build/libs
RUN mv ${JAR_PATH}/*.jar /app/app.jar

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar" ]

 

# Dockerfile
# C:\springstudy\docker-test-db\Dockerfile

FROM mysql:latest

COPY init.sql /docker-entrypoint-initdb.d

ENV MYSQL_ROOT_PASSWORD=1234
ENV MYSQL_DATABASE=spring-test-db
ENV MYSQL_HOST=%

CMD ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]

 

# init.sql
# C:\springstudy\docker-test-db\init.sql

CREATE TABLE MEMBER(
    USER_ID BIGINT AUTO_INCREMENT PRIMARY KEY,
    USERNAME VARCHAR(255),
    PASSWORD VARCHAR(255),
    ROLE VARCHAR(255)
);

CREATE TABLE IP_ADDR (
    ID BIGINT AUTO_INCREMENT PRIMARY KEY,
    IP_ADDR VARCHAR(255)
);

 

# docker-compose.yml
# C:\springstudy\docker-compose.yml

version: '3'
services:
  my-database:
    build:
      context: ./docker-test-db
      dockerfile: Dockerfile
    ports:
      - 3307:3306
    volumes:
      - ./docker-test-db/store:/var/lib/mysql
    networks:
      - my-network
  my-server:
    build:
      context: ./
      dockerfile: Dockerfile
    restart: always
    ports:
      - 8080:8080
    depends_on:
      - my-database
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://my-database:3306/spring-test-db?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
      #?useSSL=false&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_DRIVER: com.mysql.jdbc.Driver
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 1234
    networks:
      - my-network

networks:
  my-network:

 

# application.yml
spring:
  profiles:
    active:
      - prod

 

# application-prod.yml
spring:
  datasource:
      driver-class-name: ${SPRING_DATASOURCE_DRIVER}
      url: ${SPRING_DATASOURCE_URL}
      username: ${SPRING_DATASOURCE_USERNAME}
      password: ${SPRING_DATASOURCE_PASSWORD}

  jpa:
    hibernate:
      ddl-auto: none​

 

실행 화면

이미지가 잘 생성 되었다.

 

컨테이너가 잘 생성 되었다.

 

접속도 잘 된다.

 

 

다음에는 NGINX와 redis에 대해 공부해보자

ci/cd도...

 

댓글