LoginSignup
21
17

Django本番環境をNginx+GunicornでDocker上に構築

Last updated at Posted at 2021-07-24

Djangoのrunserverコマンドで動かすサーバーは、あくまで簡易的な開発用サーバーです。本番運用する場合にはセキュリティやパフォーマンスの観点からWebサーバー(リバースプロキシ)とApplicationサーバー(WSGIサーバー)を別途構築する必要があります。
今回、WebサーバーにはNginxを、アプリケーションサーバーにはGunicornを用いてDocker上に構築します。

環境

ソフト バージョン
OS MacOS Catalina 10.15.7
docker engine 20.10.5
docker compose 1.29.0
Django 3.2.5
Gruncorn 20.1.0
Nginx 1.17.7

ディレクトリ構成

.
├── app           # Djangoアプリ
├── config        # Django設定関係
│   ├── local_settings.py
│   ├── settings.py
│ 
├── Dockerfile
├── docker-compose.yml
├── docker.env
├── gunicorn.conf
├── manage.py
└── requirements.txt

Django設定ファイル

開発環境用にlocal_settings.pyファイルを作成し、'SECRET_KEY'、'DEBUG'、'ALLOWED_HOSTS'のデフォルト設定はそちらに移行。
開発用サーバーを起動する際には、settingsオプションで'local_settings.py'ファイルを指定する。

config/local_settings.py
from .settings import *

SECRET_KEY = 'XXXXX'
DEBUG = True
ALLOWED_HOSTS = []

# 開発用サーバ起動コマンド
# python manage.py runserver --settings config.local_settings

settings.pyファイルには本番環境設定を記述する。'SECRET_KEY'、'ALLOWED_HOSTS'は環境変数からの引用とし、'DEBUG'はFalseにする。

config/settings.py
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
DEBUG = False
ALLOWED_HOSTS = list(os.environ.get('ALLOWED_HOSTS','localhost').split(' '))

STATIC_URL = '/static/'
STATICFILES_DIRS = [str(BASE_DIR / 'static')]
STATIC_ROOT = str(BASE_DIR / 'static_root')

Dockerファイルの設定

Dockerコンテナ内にpython環境を構築し、requirements.txtで定義したDjangoとGunicornをインストール。
gunicornコマンドでGunicornを起動し、config/wisg.pyを読み込み、UNIXドメインソケットをバインドする。

Dockerfile
FROM python:3.9.6-alpine

WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
RUN mkdir -p /var/run/gunicorn

CMD ["gunicorn", "config.wsgi", "--bind=unix:/var/run/gunicorn/gunicorn.sock"]
requirements.txt
Django==3.2.5
gunicorn==20.1.0

Docker Composeファイルの設定

gunicornイメージはDockerファイルからbuildし、nginxイメージはDocker Hubからダウンロードする。
gunicornコンテナ、nginxコンテナの双方でgunicronボリュームにマウントし、UNIXソケット通信を行う。
コンテナ内のnginx設定ファイル(default.conf)をホスト側で作成したgunicorn.confファイルにマウントする。
Djangoアプリの'DJANGO_SECRET_KEY'と'ALLOWED_HOSTS'は環境変数として設定する。

docker-compose.yml
version: '3'

services:
  gunicorn:
    build: .
    image: gunicorn:20.1.0
    container_name: gunicorn
    volumes:
      - .:/usr/src/app/
      - gunicorn:/var/run/gunicorn
    env_file: docker.env
    stdin_open: true
    tty: true

  nginx:
    image: nginx:1.17.7
    container_name: nginx
    depends_on:
      - gunicorn
    ports:
      - "80:80"
    volumes:
      - ./gunicorn.conf:/etc/nginx/conf.d/default.conf
      - ./static_root:/var/www/mysite/static
      - gunicorn:/var/run/gunicorn
volumes:
  gunicorn:
    driver: local
gunicorn.conf
upstream gunicorn-django {
    server unix:///var/run/gunicorn/gunicorn.sock;
}
server {
    listen 80;
    server_name localhost;
    location / {
        try_files $uri @gunicorn;
    }
    location /static/ {
        root /var/www/mysite;
    }
    location @gunicorn {
        proxy_pass http://gunicorn-django;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
docker.env
DJANGO_SECRET_KEY='XXXXX'
ALLOWED_HOSTS='example.com'
# 開発環境の場合は、ALLOWED_HOSTS='localhost 127.0.0.1'

起動コマンド

docker-compose upコマンドでコンテナを生成・起動する。
localhostにアクセスし画面が出ればOK

$ docker-compose up -d

スクリーンショット 2021-07-24 9.01.58.png
スクリーンショット 2021-07-24 9.02.23.png

参考

21
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
17