이재홍의 언제나 최신 Docker - Unit 11.2 Django Dockerfile 작성하기

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

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

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

Django Dockerfile 작성하기

Django 설치가 끝났으니 예제 Django 애플리케이션을 생성합니다.

~$ django-admin startproject exampleapp

exampleapp 디렉터리가 생성되었습니다. exampleapp/exampleapp 디렉터리 아래에 있는 settings.py 파일을 열고 다음과 같이 수정합니다.

ALLOWED_HOSTS'*'를 넣어 모든 호스트에서 접근할 수 있도록 설정합니다.

~/exampleapp/exampleapp/settings.py
ALLOWED_HOSTS = ['*']

데이터베이스 설정입니다.

~/exampleapp/exampleapp/settings.py
import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'exampleapp',
        'USER': 'root',
        'PASSWORD': os.getenv('MYSQL_ROOT_PASSWORD'),
        'HOST': os.getenv('MYSQL_HOST') or 'db',
        'PORT': '3306',
    }
}
  • ENGINE: MySQL을 사용하기 위해 django.db.backends.mysql을 설정합니다.
  • NAME: 데이터베이스 이름입니다. exampleapp를 설정합니다.
  • USER: root를 설정합니다.
  • PASSWORD: 환경 변수의 MYSQL_ROOT_PASSWORD를 사용하도록 설정합니다.
  • HOST: or 연산자를 이용하여 개발 환경과 데이터베이스 컨테이너에서 사용할 데이터베이스 호스트를 각각 설정합니다. 개발을 할 때는 환경 변수의 MYSQL_HOST에 데이터베이스 컨테이너의 IP 주소를 설정합니다. 그리고 데이터베이스 컨테이너를 연결할 때는 별칭을 db로 할 것이므로 db로 설정합니다.
  • PORT: 3306번을 설정합니다.

PostgreSQL 사용하기
다음은 PostgreSQL 사용 설정입니다.

~/exampleapp/exampleapp/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'exampleapp',
        'USER': 'postgres',
        'PASSWORD': os.getenv('POSTGRES_PASSWORD'),
        'HOST': os.getenv('POSTGRES_HOST') or 'db',
        'PORT': '5432',
    }
}

다음 내용을 Dockerfile로 저장합니다.

~/exampleapp/Dockerfile
FROM alpine:latest

RUN apk add tzdata
ENV TZ=Asia/Seoul

RUN apk add python3 py3-pip py3-mysqlclient nginx gcc

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
ADD default.conf /etc/nginx/http.d/default.conf

RUN pip install django gunicorn mysqlclient

ADD ./ /var/www/exampleapp
WORKDIR /var/www/exampleapp
RUN chmod +x entrypoint.sh

EXPOSE 80

ENTRYPOINT ./entrypoint.sh

지금까지 우분투 22.04를 기반으로 이미지를 구성해보았으니 이번에는 Alpine Linux를 기반으로 하겠습니다.

  • FROM으로 alpine:latest를 기반으로 이미지를 생성하도록 설정합니다.
  • Alpine Linux는 타임존 설정이 없습니다. 따라서 apk add 명령으로 tzdata를 설치해주고, ENVTZ=Asia/Seoul 환경 변수를 설정해줍니다.
  • apk add 명령으로 python3, py3-pip, py3-mysqlclient, nginx, gcc를 설치합니다.
  • nginx를 데몬이 아닌 foreground로 실행하도록 설정합니다. nginx를 데몬 상태로 실행하면 Docker 컨테이너가 바로 정지되므로 주의합니다.
  • /etc/nginx/http.d 디렉터리에 default.conf 파일을 추가합니다.
  • pip install 명령으로 django, gunicorn, mysqlclient를 설치합니다.
  • Django 애플리케이션 디렉터리를 /var/www/exampleapp 디렉터리에 추가합니다.
  • entrypoint.sh 파일을 실행할 수 있도록 권한을 설정합니다.
  • EXPOSE에 80을 설정하여 80번 포트에 접속할 수 있도록 합니다.
  • ENTRYPOINT에 ./entrypoint.sh 파일을 설정하여 컨테이너가 시작되었을 때 스크립트 파일을 실행합니다.

PostgreSQL 사용하기

다음은 PostgreSQL 사용 설정입니다.

~/exampleapp/Dockerfile
RUN apk add python3 py3-pip postgresql-dev python3-dev musl-dev nginx gcc

RUN pip install django gunicorn psycopg2

이제 Nginx 설정 파일을 작성합니다. 다음 내용을 default.conf 파일로 저장합니다.

~/exampleapp/default.conf
server {
  listen 80;
  server_name _;

  location /static/ {
    alias /var/www/exampleapp/static/;
  }

  location / {
    proxy_set_header Host $host;
    proxy_pass http://unix:/tmp/gunicorn.sock;
  }
}
  • server 항목을 설정합니다.
    • listen 80을 설정하여 80번 포트를 사용합니다.
    • Nginx는 정적 파일(html, js, css 등)을 전송할 것이므로 Django 애플리케이션 디렉터리 아래의 static 디렉터리를 설정합니다(각자 상황에 맞게 수정합니다).
    • Nginx로 / 경로는 proxy_pass http://unix:/tmp/gunicorn.sock;와 같이 유닉스 소켓(/tmp/gunicorn.sock)으로 보냅니다. 이렇게 설정하면 정적 파일은 Nginx가 전송하고, 나머지 RESTful API는 Django가 처리하게 됩니다.

다음 내용을 entrypoint.sh로 저장합니다.

~/exampleapp/entrypoint.sh
#!/bin/sh

python3 manage.py migrate
gunicorn exampleapp.wsgi -b unix:/tmp/gunicorn.sock -D
nginx
  • python manage.py migrate을 실행하여 데이터베이스 테이블을 마이그레이션합니다.
  • gunicornexampleapp.wsgi를 설정합니다. <Django 애플리케이션 이름>.wsgi 형식입니다.
    • -b 옵션을 사용하여 /tmp/gunicorn.sock에 유닉스 소켓을 생성합니다.
    • -D 옵션을 사용하여 데몬 모드로 실행합니다.
  • 앞에서 nginx.confdaemon off;로 설정했으므로 Nginx 웹 서버를 foreground로 실행합니다. 여기서 Nginx를 foreground로 실행하지 않으면 docker run -d로 컨테이너를 생성해도 바로 정지되므로 주의합니다.

docker build 명령으로 이미지를 생성합니다.

~/exampleapp$ sudo docker build --tag django .

저작권 안내

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

Published

2022-10-03