[Spring Boot + MySQL] docker-compose 세팅

들어가며

docker-compose를 이용하여 Spring Boot 애플리케이션과 MySQL 서버를 docker 컨테이너로 띄어보았다.

 

먼저 다음 두 파일은 같은 디렉토리에 있어야 한다.

- docker-compose

- Dockerfile

 

docker-compose 위치

같은 위치에 있어야만 docker-compose.yml에서 Dockerfile 인식이 가능하다.

 

설정파일

 

다음으로 docker-compose.yml 내용을 살펴보겠다.

version: '3'  
  
services:  
  database: 
    container_name: mysql_db 
    image: mysql/mysql-server:5.7  
    restart: unless-stopped # 수동으로 종료하지 않는이상 계속 재시작
    environment: 
      MYSQL_DATABASE: users_db # 데이터베이스 이름
      MYSQL_ROOT_HOST: '%' 
      MYSQL_ROOT_PASSWORD: 1234 # 루트 비밀번호
      TZ: 'Asia/Seoul' # default time zone
    ports:  
      - "3307:3306" # 필자는 3306포트가 host에서 사용중이라 3307로 대체
    volumes:  
      - mysql-data:/var/lib/mysql # MySQL 데이터 저장 위치 연결 (이미지 삭제 후 다시 생성 하여도 기존에 데이터가 남아있도록 함)
    command:  
      - "mysqld" # 데이터베이스 실행 명령어
      - "--character-set-server=utf8mb4"  
      - "--collation-server=utf8mb4_unicode_ci"  
    networks:  
      - test_network # 아래에서 정의한 network 적용
  
  application: 
    container_name: docker-compose-test  
    restart: on-failure # 실패시에 재시작
    build:  
      context: ./  
      dockerfile: Dockerfile # Dockerfile을 이용하여 build
    ports: 
      - "8080:8080" 
    environment:  
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql_db:3306/users_db # 위에서 정의한 컨테이너 이름인 mysql_db로 연결
      SPRING_DATASOURCE_USERNAME: "root" 
      SPRING_DATASOURCE_PASSWORD: "1234"  
    depends_on:  
      - database  # database가 실행 되고 실행하도록 설정
    networks:  
      - test_network  # mysql과 같은 네트워크를 사용
  
networks:  
  test_network:  
    driver: bridge # bridge로 하여 mysql, spring boot app이 서로 통신 가능하도록 설정
  
volumes:  
  mysql-data: # "mysql-data"라는 이름의 볼륨 정의, MySQL 데이터 저장용

 

다음으로 Spring Boot Application 이미지를 만들 수 있도록 Dockerfile을 만들어줘야 한다.

# OpenJDK 17 JDK slim 이미지를 사용하여 Docker 이미지 생성
FROM openjdk:17-jdk-slim 

# 이 이미지에 대한 작성자 정보 설정
LABEL authors="jyp"

# 컨테이너의 작업 디렉토리를 /app으로 지정
ENV APP_HOME=/app
WORKDIR $APP_HOME

# 현재 디렉토리의 모든 파일을 컨테이너의 작업 디렉토리에 복사
COPY . ./

# Gradle을 사용하여 애플리케이션 빌드, 테스트는 제외
RUN ./gradlew build -x test --stacktrace

# 빌드된 JAR 파일을 /app 디렉토리에 복사
COPY build/libs/study.management-0.0.1-SNAPSHOT.jar /app/study.management-0.0.1-SNAPSHOT.jar

# 8080번 포트를 외부에 노출
EXPOSE 8080

# JAR 파일을 실행하는 엔트리포인트 설정
ENTRYPOINT ["java", "-jar", "/app/study.management-0.0.1-SNAPSHOT.jar"]

 

docker compose 명령어

 

이제 docker-compose 명령어를 이용하여 실행시킬 일만 남았다.

 

우선 기본적으로 docker compose 명령어는 docker-compose.yml 파일이 있는 위치에서 실행해야 한다. 만약 실행 위치에 docker-compose.yml 파일이 없거나, 이름이 다르다면 -f 옵션을 통해 파일 경로를 주어야 한다.

 

ex)

docker compose -f ./docker-compose.prod.yml up

 

1. docker compose build
docker-compose.yml 파일에서 필요한 이미지를 찾아서 빌드한다.

2. docker compose up 

docker-compose.yml 파일에서 서비스에 필요한 모든 컨테이너를 생성하고 시작한다. 만약 컨테이너가 빌드되지 않았거나, 혹은 빌드 된 이후 도커파일의 변동으로 다시 빌드되야 하는 경우, 이미지를 빌드한 후 컨테이너를 생성, 시작한다.

 

만약 이미지를 새로 빌드하고 싶다면 --build 옵션을 추가하면 된다.

docker compose up --build

 

 

3. docker compose down 

해당 프로젝트의 컨테이너를 중단하고, 제거한다. network나 volume또한 제거된다. 따라서 단순히 잠시 중단한 뒤 나중에 다시 시작하고 싶다면 docker compose stop 혹은 docker compose 가 실행되고 있는 터미널에서 ctrl + C를 통해 중단해야 한다.

4. docker compose stop 

명시한 서비스, 혹은 명시한 서비스가 없다면 전체 컨테이너를 중단한다.
down과는 다르게 단순 중단이므로 start 명령어로 다시 시작할 수 있다.

5. docker compose start 

생성된 후에 멈췄던 컨테이너를 시작하는 명령어. 쉽게 말해 up을 통해 생성되고, 시작한 이후 docker compose stop 혹은 Ctrl + C를 통해 중단된 서비스를 다시 시작할 수 있다.

6. docker copmose restart

docker compose stop + docker compose start
만약 build 후 restart를 한다면 직전 생성된 이미지를 사용한다. 따라서 돌아가고 있는 컨테이너의 이미지를 바꿔야 한다면,

docker compose build <service>
docker compose restart <service>

위와 같이 빌드 한 후 재시작하면 된다.

7. docker compose ps

현재 동작하는 컨테이너를 보여준다.

8. docker compose logs

해당 서비스의 로그를 보여준다.

9. docker exec <container_id/name> <command>

현재 돌아가는 컨테이너에 명령어를 전달해준다.
만약 conatiner_name을 지정해주지 않았다면, docker ps를 통해 container id를 먼저 얻어야 한다.

이것을 활용해서 현재 컨테이너에 터미널을 접속할 수 있다.
-i는 interactive 옵션으로 터미널을 통한 입력이 가능하게 해주고, -t옵션은 컨테이너의 출력을 터미널로 전달해주므로 두 옵션을 함께 사용해 쉘을 열면 된다.

docker exec -it <container_id/name> /bin/bash

이미지에 따라, /bin/bash를 찾을 수 없다고 뜰 수 있다. 특히 alpine이미지에서 이렇게 뜨는 경우가 많은데, 이 때는 /bin/sh를 대신 써주면 된다.

10. docker exec config

설정 값 등을 보여준다. 환경변수 등이 제대로 들어갔는지 확인하고 싶을 때 사용하면 유용하다.

'DevOps' 카테고리의 다른 글

Nginx에 SSL 적용 및 Reverse Proxy 설정  (0) 2024.11.21
minikube service 외부 접속 안되는 이유  (0) 2024.08.27
Jenkins CI/CD with github  (0) 2024.06.07
Docker에 nginx 컨테이너 올리기  (0) 2024.03.28