본문 바로가기
DevOps/Docker

[프리온보딩] Docker Compose

by DUSTIN KANG 2023. 12. 14.

Docker Compose

 

도커 컴포즈(Docker Compose)단일 서버에서 여러 개의 컨테이너를 하나의 서버스로 묶어 관리할 수 있는 환경을 제공한다.

예를들어, Django을 Docker에 띄우기 위해선 SQL 서버와 같이 띄어야한다는 것이다.

지난 포스팅에서는 도커 네트워크를 통해 워드프레스를 띄우는 연습을 진행했다. 작업을 해본 결과 순서에 맞게 올리지 않으면 오류가 발생되는 문제가 있었다. 

 

이번에는 Docker Compose를 통해 워드프레스를 올려보기로 했다.

Docker Compose는 컴포즈 파일을 Docker CLI로 번역하여 올리게 된다. 그럼, 컴포즈 파일을 어떻게 만들까?

컴포즈 파일은 `yaml`파일을 통해 만들 수 있다.

먼저 Docker와 연결할 위치에 `docker-compose.yml` 파일을 만들어준다.

 

version: "3.0"

services:
  db:
    image: mysql:latest
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: docker_pro
      MYSQL_PASSWORD: docker_pro_pass
  
  app:
    depends_on: 
      - db
    image: wordpress:latest
    volumes:
      - ./app_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: docker_pro
      WORDPRESS_DB_PASSWORD: docker_pro_pass

 

다음 코드를 작성하고 `docker compose up`을 하게되면 db와 app 두가지 컨테이너가 올라가는 것을 확인할 수 있다.

app폴더와 db 폴더가 제대로 마운트되었다는 것도 볼 수 있다.
두 컨테이너가 잘 올라간 것도 볼 수 있다.
네트워크를 따로 지정하지 않아도 생성된 것도 볼 수 있다.

 

 

Docker Compose 자세히 보기

이번엔 Docker Compose를 자세히 들여다 보자.

Docker Compose 파일에는 다음과 같은 구성으로 이루어져 있다.

Docker Compose file

 

version

compose 파일을 작성하기 위해 처음 부분에 `version`을 명시한다.

보통 3.0으로 설정하는 것이 일반적이고 1.0 버전은 이미 사라졌다. 웬만하면 최신 버전을 사용하는 게 좋다고 한다.

 

Services

실행하고자 하는 컨테이너를 작성하는 부분이다.

상위 이미지에 `db`가 이전에 shell로 작성했을 때 이름 옵션을 지정하는 것과 같다.

image 컨테이너를 생성할 때 사용할 이미지를 지정한다.
build 정의된 도커파일에서 이미지를 빌드해 서비스의 컨테이너를 생성하도록 설정한다.
environment 환경변수를 설정한다. `-e`옵션과 동일하다.
command 컨테이너가 실행될 때 수행할 명령어를 의미한다. `docker run` 이후에 붙는 명령어와 동일하다.
depends_on 컨테이너 간 의존성을 주입한다. 명시된 컨테이너가 먼저 생성되고 실행된다.
ports 개방 포트를 지정한다. `-p` 옵션과 동일하다.
expose 링크로 연계된 컨테이너에게만 공개할 포트를 설정한다.
volumes 컨테이너의 볼륨을 마운트한다. `-v` 옵션과 동일하다.
restart 컨테이너가 종료될떄 재시작 정책을 정한다. (no: 재시작하지 않는다. always : 외부 영향에 의해 종료될때 항상 재시작한다.(강제로 끄기 전) onfailure : 오류가 발생했을 때 재시작한다.)

 

Network

아까 상위 그림을 보았듯, 자동으로 네트워크가 생성되었다.

우리는 Docker compose를 통해 네트워크도 설정할 수 있다.

networks:
  wordpress_net:
    driver: bridge

 

위 코드로 작성하면, 네트워크의 이름과 드라이버를 지정해서 업로드할 수 있다.

해당 네트워크의 상세정보를 확인해보면 두 컨테이너가 올라와 있는 것을 확인할 수 있다.

app과 db 이 두가지 컨테이너가 하나의 네트워크에 있다는 것을 볼 수 있다.

 

volumes

컨테이너의 데이터를 관리할 수 있다. 컨테이너의 볼륨을 마운트 할 때 지정한다.

  • `vloumes _from` : 다른 컨테이너로부터 볼륨을 마운트하고자 할때 _from 키워드를 사용한다.
  db:
    image: mysql:latest
    volumes:
      - ./db_data:/var/lib/mysql

 

컴포즈 명령어

이번엔 도커 컴포즈의 명령어를 알아보자.

컴포즈 명령어는 간단히 다음과 같다. 그리고 실행중인 컴포즈 파일을 내릴 때는 `up` 대신 `down`을 하면 된다.

 

Docker Compose로 Django 구축하기

이번에는 Docker Compose를 이용해 Django 애플리케이션을 띄우는 실습을 진행해보려고 한다.

사실, Docker에서 친절하게 공식문서로 제공해주고 있다.

 

1. 빈 디렉터리에 Dockerfile을 생성한다.

먼저, 디렉터리에 아래와 같은 python Dockerfile을 생성한다.

이 Dockerfile에는 파이썬 환경 이미지를 실행하고 파이썬 환경에서 Django 프레임워크를 실행할 것이다.

Django 프레임워크를 실행하기 위해 `requirements.txt`의존성 파일에 django 프레임워크와 postgresql 서버를 설치할 것이다.

 

FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1 # 파이썬 .pyc 파일을 생성하지 않도록 한다.
ENV PYTHONUNBUFFERED=1 # 파이썬 로그가 버퍼링 없이 출력한다.
WORKDIR /web # web 디렉토리를 시작 디렉토리로 설정
COPY . . # web 디렉토리로 복사
RUN pip install -r requirements.txt # 실행

 

Django>=3.0,<4.0
psycopg2>=2.8

 

2. Docker-compose

이번엔 실제로 디렉터리에 있는 docker-compose.yml 파일을 생성하고 compose를 실행한다.

docker compose 파일에는 Postgresql DB와 Django를 실행하도록 작성한다.

version: '3'

# 띄울 컨테이너 목록
services:
  # Django 컨테이너
  web:
    container_name : django_service
    # django build 옵션, 현재 디렉터리에 있는 Dockerfile 이미지를 빌드
    build: .
    # 실행 커맨드
    command: python manage.py runserver 0:8000
    # 포트 번호
    ports:
      - "8000:8000"
    # 볼륨 마운트
    volumes:
      - .:/web
    # 환경 변수
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    # 의존 순서 DB 먼저 실행
    depends_on:
      - db
  
  # postgres 컨테이너
  db:
  	container_name : postgres_service
    image: postgres # 사용할 이미지
    environment: # 환경 변수
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

 

다음과 같이 작성했으면 `docker compose run`을 통해 프로젝트를 생성해보자

docker compose run web django-admin startproject docker_project .

 

프로젝트를 생성하게되면 아래와 같은 local에서도 프로젝트가 생성될 것이다.

 

Overlaying a project into an existing directory won't replace conflicting files.
마운트하는 경로에 같은 파일이 존재하거나 생성될 수도 있다. 이럴 땐 기존 파일이 존재하는지 확인허가나 위치를 바꿔주면 된다. 

 

3. Django 환경 설정 후 실행

Django 환경 파일에서 Database를 재설정하도록하자. 이전에 환경 변수로 설정한 DB 정보를 settings.py 파일에 변경해주면 된다.

 

import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('POSTGRES_NAME'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': 'db',
        'PORT': 5432,
    }
}

 

이제 `docker compose up` 명령어로 서비스가 돌아가게 하면 된다.

 

 

이번엔 마이그레이션을 해보자.

docker compose exec web python manage.py migrate

 

그다음, `psql` 커맨드로 Postgresql DB에서 확인해보면 생성된 테이블을 확인할 수 있다.

docker compose exec db psql postgres postgres