docker-compose를 이용하여 MySQL Docker image를 pull 받고 container 환경에서 실행한다.

Docker volume을 이용하여 container가 down 되더라도 데이터가 남아있게 만든다.

Docker container로 실행되는 MySQL을 DataGrip, Django와 연결한다.

docker-compose.yml 작성

[docker-compose.local.yml]

version: "3.9"

services:
  db:
    image: mysql:8.0
    platform: linux/amd64
    container_name: mysql
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
    restart: always
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    env_file:
      - .env.local
#    healthcheck:
#      test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
#      timeout: 20s
#      retries: 10

  app:
    image: anam-earth:latest
    build:
      context: .
      dockerfile: Dockerfile.local
    container_name: anam-earth
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    depends_on:
      - db
#      db:
#        condition: service_completed_successfully

volumes:
    mysql_data:

version: v2와 v3이 있다. v3가 최신이다. Docker Desktop에서 v2를 사용하도록 설정할 수 있다.

platform: docker container가 실행되는 운영체제와 하드웨어이다. Mac M1에서는 명시해야 한다.

command: mysqld 뒤에 붙는 인자만 적어주어도 충분하다. utf8mb4는 기본 문자 외에 이모지도 포함한다. utf8mb4_general_ci는 올바른 한글 인식을 위해 필요하다.

restart:

ports: <external>:<internal> 형태로, 현재 내 Windows 상에 mysqld가 실행 중이므로 3306이 아닌 다른 값을 사용한다. 컨테이너 내부의 mysql은 3306에서 반드시 실행된다. (mysql.cnf에서 수정 가능)

env_file: MYSQL_USER, MYSQL_DATABASE, MYSQL_PASSWORD 등의 환경변수를 일일이 environment에 나열하는 대신, .env 파일로 간편히 관리한다.

*healthcheck*: app의 depends_on에서 mysql이 단순히 시작될 때가 아닌, mysql과 connection이 생겼을 때 anam-earth 컨테이너를 run 시작하기 위해 설정한다.

volumes: 외부에서 쓰기 연산하지 않으므로 bind mount가 아닌 volume을 이용. volume은 Docker에서 관리되므로 더 안정적이다. v3 문법은 위와 같고, v2의 경우 따로 volume으로 사용되는 컨테이너를 정의해줘야 한다.

Volume vs. Bind Mount