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

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

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

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

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

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

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

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

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

~/exampleapp$ sudo docker run -d --name app -p 80:80 \
    --network django-network \
    -e MYSQL_ROOT_PASSWORD=examplepassword \
    -e MYSQL_HOST=db \
    django

이제 이 명령들을 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: exampleapp
    networks:
      - django-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:
      - 80:80
    environment:
      MYSQL_ROOT_PASSWORD: examplepassword
      MYSQL_HOST: db
    depends_on:
      db:
        condition: service_healthy
    networks:
      - django-network

networks:
  django-network:

volumes:
  mysql-data:
  • networks: Django 컨테이너에서 데이터베이스 컨테이너에 연결할 수 있도록 네트워크를 생성합니다. docker network create 명령과 같으며 이름은 django-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: Django 앱 컨테이너이며 이름은 app으로 지정했습니다.
    • build: Docker Compose로 컨테이너를 생성하면서 이미지를 빌드할 때 사용합니다.
      • context: 빌드할 컨텍스트 디렉터리입니다. 현재 디렉터리 .을 지정합니다.
      • dockerfile: 빌드할 Dockerfile 경로입니다. ./Dockerfile를 지정합니다.
    • ports: Django의 포트 번호입니다. 80:80으로 설정합니다.
    • environment: Django 앱을 실행할 때 사용할 환경 변수를 설정합니다. MYSQL_ROOT_PASSWORDMYSQL_HOSTdocker run과 동일하게 넣어줍니다.
    • depends_on: Django에서 ORM으로 MySQL 데이터베이스에 테이블을 생성해야 하는데, app 컨테이너가 먼저 생성되면 안 됩니다. 따라서 depends_ondb를 설정하여 db 컨테이너가 생성된 뒤에 app 컨테이너가 생성되도록 합니다. 특히, conditionservice_healthy를 지정해서 healthcheck가 정상 상태가 될 때까지 기다립니다. 즉, MySQL 데이터베이스가 완전히 생성될 때까지 기다립니다.
    • networks: 데이터베이스 컨테이너에 연결할 수 있도록, 최상위 networks에서 만든 네트워크 django-network를 연결해줍니다.

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

$ sudo docker compose up -d
[+] Running 4/4
 ⠿ Network exampleapp_django-network  Created                         0.7s
 ⠿ Volume "exampleapp_mysql-data"     Created                         0.2s
 ⠿ Container exampleapp-db-1          Started                         4.5s
 ⠿ Container exampleapp-app-1         Started                         6.5s

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

The install worked successfully! Congratulations! 화면이 표시되면 Django 컨테이너와 MySQL 컨테이너가 정상적으로 생성된 것입니다.

이전 Docker Compose 이미지 삭제하기
다른 예제에서 Docker Compose로 생성한 이미지가 있었다면, 이번 예제에서 이전 이미지가 컨테이너로 생성될 수 있습니다. 이때는 이미지를 삭제하거나 이미지를 새로 빌드해줍니다.

다음과 같이 이미지를 삭제합니다.

$ sudo docker rmi exampleapp-app

또는, 다음과 같이 docker compose build 명령으로 이미지를 새로 빌드합니다.

$ sudo docker compose build

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

$ sudo docker compose down
[+] Running 3/3
 ⠿ Container exampleapp-app-1         Removed                        11.9s
 ⠿ Container exampleapp-db-1          Removed                         3.4s
 ⠿ Network exampleapp_django-network  Removed                         0.9s

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

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

저작권 안내

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

Published

2022-10-03