이재홍의 언제나 최신 Docker - Unit 12.4 Docker Compose로 Spring Boot와 MySQL 컨테이너 생성하기

저작권 안내
  • 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
  • 책 또는 웹사이트의 내용을 발췌, 요약하여 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.

Docker로 Spring Boot 애플리케이션 구축하기

이재홍 http://www.pyrasis.com

Docker Compose로 Spring Boot와 MySQL 컨테이너 생성하기

docker-compose.yml 파일을 작성하기 전에 Spring Boot와 MySQL 컨테이너의 docker run 명령을 살펴보겠습니다.

먼저 MySQL 데이터베이스 컨테이너입니다.

~/gs-spring-boot/initial$ sudo docker network create spring-boot-network
~/gs-spring-boot/initial$ sudo docker volume create mysql-data
~/gs-spring-boot/initial$ sudo docker run -d --name db \
    -p 3306:3306 \
    --network spring-boot-network \
    -v mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=examplepassword \
    -e MYSQL_DATABASE=example \
    mysql:5.7

그다음으로 Spring Boot 앱 컨테이너입니다.

~/exampleapp$ sudo docker run -d --name app -p 8080:8080 \
    --network spring-boot-network \
    -e MYSQL_HOST=db \
    spring-boot

이제 이 명령들을 docker-compose.yml로 옮겨보겠습니다. 다음 내용을 ~/exampleapp/docker-compose.yml로 저장합니다.

~/exampleapp/docker-compose.yml
version: '3.8'

services:
  db:
    image: mysql:5.7
    ports:
      - 3306:3306
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: examplepassword
      MYSQL_DATABASE: example
    networks:
      - spring-network
    healthcheck:
      test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD']
      interval: 10s
      timeout: 2s
      retries: 100

  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 8080:8080
    environment:
      MYSQL_HOST: db
    depends_on:
      db:
        condition: service_healthy
    networks:
      - spring-network

networks:
  spring-network:

volumes:
  mysql-data:
  • networks: Spring Boot 컨테이너에서 데이터베이스 컨테이너에 연결할 수 있도록 네트워크를 생성합니다. docker network create 명령과 같으며 이름은 spring-boot-network로 지정합니다.
  • volumes: 데이터베이스 컨테이너에서 사용할 볼륨을 생성합니다. docker volume create 명령과 같으며 이름은 mysql-data로 지정합니다.
  • servicesdbapp로 나누어서 설정값을 넣습니다.
  • db: 데이터베이스 컨테이너이며 이름은 db로 지정했습니다.
    • image: MySQL의 공식 이미지 mysql:5.7을 사용합니다.
    • ports: MySQL의 포트 번호입니다. 3306:3306으로 설정합니다.
    • volumes: 최상위 volumes에서 만든 볼륨 mysql-data을 컨테이너의 /var/lib/mysql에 연결해줍니다.
    • environment: MySQL을 실행할 때 사용할 환경 변수를 설정합니다. MYSQL_ROOT_PASSWORDMYSQL_DATABASEdocker run과 동일하게 넣어줍니다.
    • networks: 컨테이너가 사용할 네트워크를 지정합니다. 최상위 networks에서 만든 네트워크 django-network를 연결해줍니다.
    • healthcheck: MySQL 컨테이너가 생성되면서 MySQL 데이터베이스도 생성하는데 이때 시간이 조금 걸립니다. MySQL 데이터베이스가 생성되지 않은 상태로 Django에서 migrate를 실행하게 되면 에러가 발생합니다. 따라서 10초 간격으로 mysqladmin ping을 실행하여 MySQL 데이터베이스가 생성되었는지 검사하고, MySQL 데이터베이스가 완전히 생성되었을 때 app 컨테이너를 생성하도록 합니다.
  • app: Spring Boot 앱 컨테이너이며 이름은 app으로 지정했습니다.
    • build: Docker Compose로 컨테이너를 생성하면서 이미지를 빌드할 때 사용합니다.
      • context: 빌드할 컨텍스트 디렉터리입니다. 현재 디렉터리 .을 지정합니다.
      • dockerfile: 빌드할 Dockerfile 경로입니다. ./Dockerfile를 지정합니다.
    • ports: Spring Boot의 포트 번호입니다. 8080:8080으로 설정합니다.
    • environment: Spring Boot 앱을 실행할 때 사용할 환경 변수를 설정합니다. MYSQL_HOSTdocker run과 동일하게 넣어줍니다.
    • depends_on: Spring Boot에서 ORM으로 MySQL 데이터베이스에 테이블을 생성해야 하는데, app 컨테이너가 먼저 생성되면 안 됩니다. 따라서 depends_ondb를 설정하여 db 컨테이너가 생성된 뒤에 app 컨테이너가 생성되도록 합니다. 특히, conditionservice_healthy를 지정해서 healthcheck가 정상 상태가 될 때까지 기다립니다. 즉, MySQL 데이터베이스가 완전히 생성될 때까지 기다립니다.
    • networks: 데이터베이스 컨테이너에 연결할 수 있도록, 최상위 networks에서 만든 네트워크 spring-boot-network를 연결해줍니다.

다음 명령을 실행하여 docker-compose.yml에 정의된 컨테이너들을 생성합니다.

$ sudo docker compose up -d
[+] Running 4/4
 ⠿ Network initial_spring-network     Created                         0.1s
 ⠿ Volume "initial_mysql-data"        Created                         0.2s
 ⠿ Container initial-db-1             Started                        12.4s
 ⠿ Container initial-app-1            Started                        12.8s

웹 브라우저에서 http://<컨테이너 IP 주소 또는 도메인>:8080으로 접속해봅니다(Docker Desktop에서 실행했다면 http://127.0.0.1:8080입니다).

다음과 같은 데이터가 표시되면 Spring Boot 앱 컨테이너와 MySQL 데이터베이스 컨테이너가 정상적으로 생성된 것입니다(새로 고침하면 데이터가 계속 누적되서 표시될 것입니다).

[{"id":1,"name":"hello","email":"hello@world.com"}]

컨테이너들을 삭제하려면 docker compose down 명령을 사용하면 됩니다.

$ sudo docker compose down
[+] Running 3/3
 ⠿ Container initial-app-1            Removed                         6.9s
 ⠿ Container initial-db-1             Removed                         2.0s
 ⠿ Network initial_spring-network     Removed                         0.3s

만약 데이터베이스 볼륨도 삭제하고 싶다면 docker volume rm 명령을 사용합니다.

$ sudo docker volume ls
DRIVER    VOLUME NAME
local     initial_mysql-data
$ sudo docker volume rm initial_mysql-data

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

2022-10-03