Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
109
Help us understand the problem. What are the problem?
@amazipangu

Djangoの環境をDocker化する(Docker + Django + Gunicorn + nginx)その1

大好きなPython3Djangoで開発しようと考え、Dockerを使って環境構築をしました。おおよそ1ヶ月(ハマりましたorz)ほどかかりました。そんな惨事を繰り返さないために記録しておきたいと思います。長くなりそうなので、docker-compose.ymlファイルを除く初期設定までを記載します。次回は、docker-compose.ymlを主に記載します。


環境の詳細

  • OS
    • 下記の仮想化ツールを利用するため、OS差異による動作差分は発生しない想定です。
  • 仮想化ツール
    • Docker
  • 言語
    • Python3
  • フレームワーク
    • Django
  • WSGI
    • Gunicorn
  • Webサーバ
    • Nginx
  • データベース
    • PostgreSQL

依存関係は下記の更新により最新化済み(2021/07/11現在)


初期設定

  1. プロジェクトディレクトリを作成して、その中に必要なディレクトリ構造とファイルを作成していきます。初期設定時のディレクトリ構造は以下の通りです。

    docker-django/
    ┣nginx
    ┃    ┗nginx.conf
    ┃    ┗mime.types 
    ┃
    ┣web
    ┃  ┗Dockerfile
    ┃  ┗Pipfile
    ┗docker-compose.yml
    
  2. Djangoコンテナを作成するためにDockerfileを作成する。

Dockerfile
FROM python:3.7-alpine
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY Pipfile /usr/src/app/
RUN apk update \
  && apk add --virtual build-tools gcc python3-dev musl-dev \
  && apk add postgresql-dev
RUN pip install pipenv
RUN pipenv lock --pre
RUN pipenv install --system --dev
RUN pipenv install --system --deploy
RUN apk del build-tools
ADD . /usr/src/app/
  • Djangoは、Pythonのイメージから作成します。
  • ENV PYTHONUNBUFFERED 1は、python環境変数の1つです。
    • バイナリレイヤ下での標準出力とエラー出力を抑制します。(PYTHONUNBUFFERED
  • アプリケーション用のディレクトリ(/usr/src/app)と静的ファイル用のディレクトリ(/usr/src/app/static)を作成します。
  • WORKDIR /usr/src/appで作業ディレクトリを指定します。以降の処理は指定されたディレクトリ下で実行されます。
  • COPY Pipfile /usr/src/app//usr/src/app/下にPipfileを追加します。
  • 開発環境で必要なライブラリ(テスティングフレームワーク等)は、Pipfile に記載し、それらをRUN pipenv install --system --devを実行してライブラリをインストールします。
  • 本番環境で必要なライブラリ(Django本体等)は、Pipfile に記載し、それらをRUN pipenv install --system --deployを実行してライブラリをインストールします。
Pipfile
[dev-packages]
flake8 = ">=3.9.2"
pytest = ">=6.2.4"
pytest-django = ">=4.4.0"
pytest-sugar = ">=0.9.4"
pytest-factoryboy = ">=2.1.0"

[packages]
django = "<=3.2.5"
psycopg2 = "<=2.9.1"
gunicorn = "<=20.10"

3.Nginx.confを編集する。

nginx.conf
worker_processes 1;

user nobody nogroup;
pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;

events {
    worker_connections 1024;
    accept_mutex off;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /tmp/nginx.access.log combined;
    sendfile on;

    upstream app_server {
        server web:8000 fail_timeout=0;
    }

    server {
        listen 80 default;
        client_max_body_size 4G;
        server_name localhost;

        keepalive_timeout 5;

        location /static/ {
               alias /usr/src/app/static/;
        }

        location / {
          try_files $uri @proxy_to_app;
        }

        location @proxy_to_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_redirect off;
            proxy_pass http://app_server;
        }

     # エラー用の静的ファイルは、適宜変更する。
        error_page 500 502 503 504 /500.html;
        location = /500.html {
            root /path/to/app/current/public;
        }
    }
}
  • mime.typesファイルの読み込みを行う。
mime.types
   types {
      text/html                             html htm shtml;
      text/css                              css;
      text/xml                              xml rss;
      image/gif                             gif;
      image/jpeg                            jpeg jpg;
      application/x-javascript              js;
      text/plain                            txt;

      ===== 以下、省略 =====
   }
  • upstreamディレクティブにて、アクセスを振り分けるサーバを定義する。
  • location /staticディレクティブにて、静的ファイルのパスを定義する。
  • location @proxy_to_appディレクティブにて、接続するアプリヶーションサーバを指定する。

次回は、docker-compose.ymlを主に記載します。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
109
Help us understand the problem. What are the problem?