この記事は、Docker(Docker-Compose)を利用しPython,Django,Postgres,Gunicorn,Nginxの開発・本番環境の構築方法を紹介します。
◆動作検証環境
・OS:mac Catalina
・Docker desktop:3.3.3(Engine:20.10.16, Compose:1.29.1)
【リモート環境】
・さくらVPSサーバー:メモリ 512M, ストレージ:SSD 25GB, CPU:1コア
・OS:Ubuntu 20.04
・Docker:20.10.7
・Docker Compose:1.23.2
【共通環境】
・Python:3.8
・Django:3.2
・Nginx:1.18.0
・Gunicorn:20.1.0
・PostgrSQL:12.0
・psycopg2-binary:2.9.1
プロジェクトファイルの設定
まずは、ローカル環境でDockerを利用しDjangoを開発する環境を準備します。
Docker-Djangoプロジェクトの作成
プロジェクト全体を管理するディレクトリを作成します。
| 1 2 3 | $ cd path/to/directry_for_your_project | 
| 1 2 3 | $ mkdir Docker-Django | 
作成したDocker-Djangoディレクトリに移動して、Djangoプロジェクト用のディレクトリ、仮想環境とプロジェクトを作成します。
| 1 2 3 | $ mkdir django_project | 
| 1 2 3 | $cd django_project | 
仮想環境の作成
virtualenvのインストールに利用するPip3のインストールとアップデートを行います。
| 1 2 3 | $ sudo -H pip3 install --upgrade pip | 
virtualenvのインストール
| 1 2 3 | $ sudo -H pip3 install virtualenv | 
virtualenvのファイル作成
さきほど作成したprojectディレクトリに移動して、ファイルを作成します。
*今回はファイル名を[ venv ]としています。必要に応じ変更します。
| 1 2 3 | $ virtualenv venv | 
仮想環境の有効化
| 1 2 3 | $ source venv/bin/activate | 
仮想環境を無効化する場合は、下記のコマンドを行います。
| 1 2 3 | (venv)$ deactivate | 
Djangoプロジェクトの作成
仮想環境を有効化しpipコマンドでDjangoをインストールします
| 1 2 3 | (venv)$ pip3 install django==3.2 | 
Djangoのプロジェクトを作成
※. をお忘れなく
| 1 2 3 | (venv)$ django-admin startproject project . | 
サーバーを立ち上げ、ロケットの確認を行います。
現在のディレクトリ構造は以下のようになります。
| 1 2 3 4 5 6 7 8 9 10 11 12 | Docker-Django └── django_project     ├── manage.py     ├── project     │   ├── __init__.py     │   ├── asgi.py     │   ├── settings.py     │   ├── urls.py     │   └── wsgi.py     └── venv | 
| 1 2 3 | (venv)$ python manage.py runserver | 
ブラウザで表示の確認
http://localhost:8000/

ローカル環境DockerとDjangoの設定
これまでの作業で、ローカルの環境でDjangoのプロジェクトを内蔵サーバーで立ち上げ、表示の確認を行いました。
この方法は一般的に、ローカル環境で開発を行う方法ですが、これからDockerをローカル環境で利用し開発する設定を行います。
Dockerファイルの作成
ローカル環境へのDockerのインストールがまだの場合は、下記のサイトからインストールします。
django_projectディレクトリ内に、Dockerファイルを以下のように作成します。
ファイル名はDockerfile とします。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | FROM python:3.8.3-alpine WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 RUN pip install --upgrade pip COPY ./requirements.txt . RUN pip install -r requirements.txt COPY . . | 
requirements.txtファイルの作成
さきほど作成したDockerファイル内でライブラリのインストールで利用するrequirements.txtをdjango_projectディレクトリに作成し、以下のように編集します。
| 1 2 3 | Django==3.2 | 
ymlファイルの作成
次に、Docker-Djangoディレクトリ内に、ymlファイルを作成します。
ファイル名はdocker-compose.yml とします。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | version: '3.7' services:   web:     build: ./django_project     command: python manage.py runserver 0.0.0.0:8000     volumes:       - ./django_project/:/usr/src/app/     ports:       - 8000:8000     env_file:       - ./.env.dev | 
環境変数ファイルの作成
ymlファイルで利用する環境変数ファイルをymlファイルと同じディレクトリに作成します。
ファイル名は、.env.devとして以下の内容で編集します。
| 1 2 3 4 5 | DEBUG=True SECRET_KEY=xxxxxxxxxxxxxxxxxxxx ALLOWED_HOSTS=localhost 127.0.0.1 [::1] | 
ymlファイルのテスト
ymlファイルを含むディレクトリへ移動し、以下のコマンドを行いymlファイルのテストを行います。
コードの書き方に間違いがある時はエラーを出力し、間違いがない場合は詳細な形でファイル内容が表示されます。
| 1 2 3 | docker-compose config | 
settings.pyファイルの作成
作成した環境変数ファイルに対応するように、profect/settings.pyを編集します。
| 1 2 3 4 5 6 7 8 9 10 11 | import os ... SECRET_KEY = os.environ.get("SECRET_KEY") DEBUG = os.environ.get("DEBUG") ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(" ") | 
ローカル用コンテナのイメージ作成、コンテナ作成、起動
ここまで設定ができたら一度イメージの作成、コンテナの作成、起動を行い、Dockerエンジンを利用した状態でDjangoのウェルカムページの確認を行います。
イメージの作成
ymlファイルを含むディレクトリへ移動し、以下のコマンドを実施します。
| 1 2 3 | $ docker-compose build | 
| 1 2 3 | $ sudo docker-compose build web | 
sudo docker-compose buildは全てのサービスをbuildします
作成したイメージの確認
以下のコマンドで作成したイメージを確認する事ができます。
| 1 2 3 | $ docker-compose images | 
以下のように表示されます。
| 1 2 3 4 5 |      Container           Repository        Tag       Image Id       Size   -------------------------------------------------------------------------- docker-django_web_1   docker-django_web   latest   946faa23f6f0   161.3 MB | 
コンテナの作成、起動
この段階でディレクトリ構造は以下のようになります。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Docker-Djnago ├── .env.dev ├── django_project │   ├── Dockerfile │   ├── db.sqlite3 │   ├── manage.py │   ├── project │   │   ├── __init__.py │   │   ├── __pycache__ │   │   ├── asgi.py │   │   ├── settings.py │   │   ├── urls.py │   │   └── wsgi.py │   ├── requirements.txt │   └── venv └── docker-compose.yml | 
-dのオプションをつけて、コンテナのの作成後、バックグラウンドで起動
| 1 2 3 | $ docker-compose up -d | 
作成したコンテナの確認
以下のコマンドで確認する事が可能です。
| 1 2 3 | $ docker-compose ps | 
以下のように表示されます(起動していないときStateの項目はExit)。
| 1 2 3 4 5 6 |        Name                   Command            State            Ports          -------------------------------------------------------------------------------- docker-django_web_1   python manage.py           Up      0.0.0.0:8000->8000/tcp,                       runserver ...                      :::8000->8000/tcp | 
ブラウザで表示を確認
http://localhost:8000/
ロケットが飛んでいればOK

以下のコマンドでログを確認します。
| 1 2 3 | $ docker-compose logs -f | 
確認ができたら、コンテナの起動を停止、削除します。
| 1 2 3 | $ docker-compose down | 
コンテナの停止のみ行う場合は以下のコマンドを実行します。
| 1 2 3 | $ docker-compose stop | 
Postgresqlの設定
Postgresqlの設定を行うために、関係するファイルを編集します。
docker-compose.ymlの編集
docker-compose.yml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | version: "3.7" services:   web:     build: ./django_project     command: python manage.py runserver 0.0.0.0:8000     volumes:       - ./django_project/:/usr/src/app/     ports:       - 8000:8000     env_file:       - ./.env.dev     depends_on:       - db   db:     image: postgres:12.0-alpine     volumes:       - postgres_data:/var/lib/postgresql/data/     env_file:       - ./.env.dev volumes:   postgres_data: | 
settings.pyファイルの編集
Postgresqlの利用に合わせ、settings.pyのDATABASEの設定を変更します。
settings.py
| 1 2 3 4 5 6 7 8 9 10 11 12 | DATABASES = {     'default': {         'ENGINE': 'django.db.backends.postgresql_psycopg2',         'NAME': os.environ.get("SQL_DATABASE"),         'USER': os.environ.get("SQL_USER"),         'PASSWORD': os.environ.get("SQL_PASSWORD"),         'HOST': os.environ.get("SQL_HOST"),         'PORT': os.environ.get("SQL_PORT"),     } } | 
環境変数ファイルの編集
settings.pyのデータベースの設定を変更し、dbコンテナの変数に対応するために、環境変数のファイルにデータベースの接続に必要な情報を追加します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | DEBUG=True SECRET_KEY=xxxxxxxxxxxxxxxxxxxx ALLOWED_HOSTS=localhost 127.0.0.1 [::1] SQL_DATABASE=db_name SQL_USER=user_name SQL_PASSWORD=password SQL_HOST=db SQL_PORT=5432 POSTGRES_USER=user_name POSTGRES_PASSWORD=password POSTGRES_DB=db_name | 
※HOSTはdocker-compose.ymlで指定したコンテナ名を設定する。
Dockerfileの編集
psycopg2の使用に合わせ、postgresqlの周辺ライブラリをインストールするよう編集します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | FROM python:3.8.3-alpine WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # install psycopg2 dependencies RUN apk update \     && apk add postgresql-dev gcc python3-dev musl-dev RUN pip install --upgrade pip COPY ./requirements.txt . RUN pip install -r requirements.txt COPY . . | 
requirements.txtファイルの作成
requirements.txtを編集します。| 1 2 3 4 | Django==3  psycopg2-binary==2.9.1 | 
Postgresqlの動作確認
関係ファイルの設定が済みましたので、コンテナを起動して動作を確認します。
| 1 2 3 | docker-compose up -d --build | 
--build のオプションをつける事で、コンテナ作成前にイメージを再ビルドします。
次にデータベースのマイグレーションを行います。
コンテナが起動している状態で以下のコマンドを実行します。
| 1 2 3 | $ docker-compose exec web python manage.py migrate --noinput | 
または、以下のコマンド行いコンテナ内でLINUX操作する方法も可能です。
| 1 2 3 | $ docker-compose exec web bash | 
上記の方法が利用できない場合は、下記の方法を試します。
| 1 2 3 | docker-compose exec web /bin/sh | 
参考)データベースのコンテナに入る場合は、webをdbと指定します。
dangoのベースディレクトリへ移動して、python manage.py migrate --noinput を実行します。
以下のようなエラーが発生した場合、以下のコマンドを実行して、作成済みのコンテナとボリュームを削除しもう一度buildとmigrateを行います。
| 1 2 3 | django.db.utils.OperationalError: FATAL: database "db_name" does not exist | 
| 1 2 3 | docker-compose down -v | 
データベースの確認
作成されたデータベースを確認するために、以下のコマンドを実行します。
| 1 2 3 | $ docker-compose exec db psql --username=user_name --dbname=db_name | 
以下のような表示となります。
| 1 2 3 4 5 6 | psql (12.0) Type "help" for help. db_name=# | 
以下のコマンドを実行します。
| 1 2 3 | # \l | 
指定した名前のデータベースを確認できればOKです
| 1 2 3 4 5 6 7 8 9 10 11 12 |                                   List of databases    Name    |   Owner   | Encoding |  Collate   |   Ctype    |    Access privileges     -----------+-----------+----------+------------+------------+-------------------------  db_name   | user_name | UTF8     | en_US.utf8 | en_US.utf8 |   postgres  | user_name | UTF8     | en_US.utf8 | en_US.utf8 |   template0 | user_name | UTF8     | en_US.utf8 | en_US.utf8 | =c/user_name           +            |           |          |            |            | user_name=CTc/user_name  template1 | user_name | UTF8     | en_US.utf8 | en_US.utf8 | =c/user_name           +            |           |          |            |            | user_name=CTc/user_name (4 rows) | 
コンテナ作成時に作成されたボリュームデータを確認する場合は、以下のコマンドを実行します。
| 1 2 3 | $ docker volume inspect docker-django_postgres_data | 
以下のように表示されます。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [     {         "CreatedAt": "2021-06-14T09:52:34Z",         "Driver": "local",         "Labels": {             "com.docker.compose.project": "docker-django",             "com.docker.compose.version": "1.29.1",             "com.docker.compose.volume": "postgres_data"         },         "Mountpoint": "/var/lib/docker/volumes/docker-django_postgres_data/_data",         "Name": "docker-django_postgres_data",         "Options": null,         "Scope": "local"     } ] | 
シェルファイルの作成
postgresqlの状態が正常である事を確認してから、コンテナを起動するためのコードを記入したシェルファイルを追加し、Dockerfileの内容も編集します。
entrypoint.shをdjango_projectディレクトリへ追加
entrypoint.sh
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/bin/sh if [ "$DATABASE" = "postgres" ] then     echo "Waiting for postgres..."     while ! nc -z $SQL_HOST $SQL_PORT; do       sleep 0.1     done     echo "PostgreSQL started" fi exec "$@" | 
作成後に、entrypoint.shの権限を変更します。
| 1 2 3 | $ chmod +x django_project/entrypoint.sh | 
次に作成したシェルファイルの実行をDockerfileへ記入します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | FROM python:3.8.3-alpine WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 RUN apk update \     && apk add postgresql-dev gcc python3-dev musl-dev RUN pip install --upgrade pip COPY ./requirements.txt . RUN pip install -r requirements.txt COPY ./entrypoint.sh . COPY . . ENTRYPOINT ["/usr/src/app/entrypoint.sh"] | 
次にシェルファイルで使用する環境変数を、.env.devに追加します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | DEBUG=True SECRET_KEY=xxxxxxxxxxxxxxxxxxxx ALLOWED_HOSTS=localhost 127.0.0.1 [::1] SQL_DATABASE=db_name SQL_USER=user_name SQL_PASSWORD=password SQL_HOST=db SQL_PORT=5432 POSTGRES_USER=user_name POSTGRES_PASSWORD=password POSTGRES_DB=db_name DATABASE=postgres | 
これ以降はPostgresqlをデータベースとして利用するため、デフォルトで作成されるSQLiteファイルを削除します。
postgresqlのコンテナを加えたのでブラウザで表示の確認をします。
この時点でのディレクトリ構造は以下の状態となります。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Docker-Django ├── .env.dev ├── django_project │   ├── Dockerfile │   ├── entrypoint.sh │   ├── manage.py │   ├── project │   │   ├── __init__.py │   │   ├── __pycache__ │   │   ├── asgi.py │   │   ├── settings.py │   │   ├── urls.py │   │   └── wsgi.py │   ├── requirements.txt │   └── venv └── docker-compose.yml | 
イメージの再ビルド
| 1 2 3 | $ docker-compose build | 
コンテナの作成、起動
| 1 2 3 | $ docker-compose up -d | 
ブラウザで表示確認
http://localhost:8000/
ロケットが飛んでいればOK

Gunicornの設定
本番環境ではGunicornをアプリケーションサーバーとして利用しますので、そちらの設定を進めます。
requirements.txtの編集
まずは、requirements.txtを編集します。
| 1 2 3 4 5 | Django==3.2  psycopg2-binary==2.9.1  gunicorn==20.1.0 | 
ymlファイルの編集
Djangoのrunserverを使用していた設定からGunicornを利用する設定にするため、ymlファイルを編集します。
docker-compose.yml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | version: "3.7" services:   web:     build: ./django_project     command: gunicorn project.wsgi:application --bind 0.0.0.0:8000     ports:       - 8000:8000     env_file:       - ./.env.dev     depends_on:       - db   db:     image: postgres:12.0-alpine     volumes:       - postgres_data:/var/lib/postgresql/data/     env_file:       - ./.env.dev volumes:   postgres_data: | 
ここまでの設定が完了したら、Gunicornを起動させる設定で動作を確かめます。
まずは、現在起動している開発環境用のコンテナを停止、削除します。
| 1 2 3 | $ docker-compose down -v | 
-vのオプションをつける事で、作成されているボリュームも削除します。
次に、本番環境用のymlファイルを指定してイメージの作成、コンテナの作成、起動を行います。
この時点のディレクトリ構造は以下のようになります。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Docker-Django ├── .env.dev ├── django_project │   ├── Dockerfile │   ├── entrypoint.sh │   ├── manage.py │   ├── project │   │   ├── __init__.py │   │   ├── __pycache__ │   │   ├── asgi.py │   │   ├── settings.py │   │   ├── urls.py │   │   └── wsgi.py │   ├── requirements.txt │   └── venv └── docker-compose.yml | 
| 1 2 3 | $ docker-compose up -d --build | 
参考)ymlファイルを指定してイメージの作成、コンテナの作成、起動した際のログを確認する際は、ログ確認コマンド実行時にもymlファイルの指定を行います。
| 1 2 3 | docker-compose logs | 
ブラウザで表示を確認します。
http://localhost:8000/

本番用のymlファイルを利用して起動すると、Djangoのrunserverの機能は使用しないため、Django内のstaticファイルは反映されなくなります。
http://localhost:8000/admin

今後の設定で、対応しますのでこのまま以降の設定を進めます。
Dockerファイルの編集
Dockerfile
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # BUILDER # FROM python:3.8.3-alpine as builder WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 RUN apk update \     && apk add postgresql-dev gcc python3-dev musl-dev RUN pip install --upgrade pip RUN pip install flake8 COPY . . COPY ./requirements.txt . RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt # FINAL # FROM python:3.8.3-alpine RUN mkdir -p /home/app RUN addgroup -S app && adduser -S app -G app ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME WORKDIR $APP_HOME RUN apk update && apk add libpq COPY --from=builder /usr/src/app/wheels /wheels COPY --from=builder /usr/src/app/requirements.txt . RUN pip install --no-cache /wheels/* COPY ./entrypoint.sh $APP_HOME COPY . $APP_HOME RUN chown -R app:app $APP_HOME USER app ENTRYPOINT ["/home/app/web/entrypoint.sh"] | 
本番環境用のymlファイルを利用したイメージ、コンテナの作成、起動
これまでの変更を反映させるために、使用していたコンテナの停止、削除、新コンテナの起動、新たな設定でデータベースのマイグレートを行います。
使用していたコンテナの停止、削除
| 1 2 3 | $ docker-compose down -v | 
新コンテナの起動
| 1 2 3 | $ docker-compose up -d --build | 
新たな設定でデータベースのマイグレート
| 1 2 3 | $ docker-compose exec web python manage.py migrate --noinpu | 
ブラウザで表示を確認します。
http://localhost:8000/

Nginxの設定
次にwebサーバとして利用するNginxの設定を行います。
ymlファイルの編集
Nginx用のコンテナを設定するために、ymlファイルを編集します。
docker-compose.yml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | version: "3.7" services:   web:     build: ./django_project     command: gunicorn project.wsgi:application --bind 0.0.0.0:8000     ports:       - 8000:8000     env_file:       - ./.env.dev     depends_on:       - db   db:     image: postgres:12.0-alpine     volumes:       - postgres_data:/var/lib/postgresql/data/     env_file:       - ./.env.dev   nginx:     build: ./nginx     ports:         - 1317:80     depends_on:         - web     volumes:   postgres_data: | 
Nginx用のフォルダの作成
次にDocker-Djangoディレクトリ内に、Nginx用のフォルダを作成し、その中にNginx用のDockerfile、nginx.confを作成します。
| 1 2 3 | $ mkdir nginx | 
Dockerfileの作成
Dockerfile
| 1 2 3 4 5 6 | FROM nginx:1.19.0-alpine RUN rm /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d | 
nginx.confの作成
nginx.conf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | upstream project {     server web:8000; } server {     listen 80;     location / {         proxy_pass http://project;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         proxy_set_header Host $host;         proxy_redirect off;     } } | 
ymlファイルの編集(Nginx仕様)
今後は、Djangoのrunserverコマンドは使用しないので、8000番ポート利用の設定をなくします。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | web:   build:     context: ./django_project     dockerfile: Dockerfile.prod   command: gunicorn project.wsgi:application --bind 0.0.0.0:8000   expose:     - 8000   env_file:     - ./.env.dev   depends_on:     - db | 
表示の確認
この時点のディレクトリ構造は以下のようになっています。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | .Docker-Django ├── .env.dev ├── django_project │   ├── Dockerfile │   ├── entrypoint.sh │   ├── manage.py │   ├── project │   │   ├── __init__.py │   │   ├── __pycache__ │   │   ├── asgi.py │   │   ├── settings.py │   │   ├── urls.py │   │   └── wsgi.py │   ├── requirements.txt │   └── venv ├── docker-compose.yml └── nginx     ├── Dockerfile     └── nginx.conf | 
使用していたコンテナの停止、削除
| 1 2 3 | $ docker-compose down -v | 
新コンテナの起動
| 1 2 3 | $ docker-compose up -d --build | 
新たな設定でデータベースのマイグレート
| 1 2 3 | $ docker-compose exec web python manage.py migrate --noinpu | 
ブラウザで表示を確認します。
http://localhost:1317/
※ポート番号はdocker-compose.ymlで指定した1317番を利用します。

Nginxを利用したStatic,Mediaファイルの表示設定
これまでは、Gunicornををwebサーバとして利用していたため、Djangoプロジェクト内のstaticファイルが利用できていませんでした(adminページで表示が崩れる)
Staticファイルの設定
今後はwebサーバにNginxを利用しますので、Staticファイルを扱う設定を加えます。
Settings.pyファイルの編集
STATIC_ROOT = os.path.join(BASE_DIR, "static") を追加します。settings.py
| 1 2 3 4 | STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, "static") | 
ymlファイルの編集
staticファイル用のボリュームを作成し、ディレクトリを指定します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | version: "3.7" services:   web:     build: ./django_project     command: gunicorn project.wsgi:application --bind 0.0.0.0:8000     volumes:         - static_volume:/home/app/web/static     expose:       - 8000     env_file:       - ./.env.dev     depends_on:       - db   db:     image: postgres:12.0-alpine     volumes:       - postgres_data:/var/lib/postgresql/data/     env_file:       - ./.env.dev   nginx:     build: ./nginx     volumes:       - static_volume:/home/app/web/static     ports:       - 1317:80     depends_on:       - web volumes:   postgres_data:   static_volume: | 
Dockerfileファイルの編集
ymlファイルのボリュームの設定に対応するために、Dockerfile内にディレクトリを作成するコードを追加します。
Dockerfile.prod
| 1 2 3 4 5 6 7 | ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME RUN mkdir $APP_HOME/static #追加 WORKDIR $APP_HOME | 
nginx.confの編集
これまで他のファイルで設定したstaticファイルの表示に対応するために、nginx.confを編集します。
nginx.conf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | upstream project {     server web:8000; } server {     listen 80;     location / {         proxy_pass http://project;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         proxy_set_header Host $host;         proxy_redirect off;     }     location /static/ {         alias /home/app/web/static/;     } } | 
表示の確認
ここまでの設定を確認するために、表示を確認します。
使用していたコンテナの停止、削除
| 1 2 3 | $ docker-compose down -v | 
新コンテナの起動
| 1 2 3 | $ docker-compose up -d --build | 
新たな設定でデータベースのマイグレート
| 1 2 3 | $ docker-compose exec web python manage.py migrate --noinpu | 
Djangoプロジェクト内のstatic関係のファイルを、nginxのstaticディレクトリへ移動するために、python manage.py collectstatic を行います。
| 1 2 3 | $ docker-compose exec web python manage.py collectstatic --no-input --clear | 
ブラウザで表示を確認します。
http://localhost:1317/
※ポート番号はdocker-compose.prod.ymlで指定した1317番を利用します。

アドミンページを表示し、staticファイル(css)が反映されている事を確認します。
http://localhost:1317/admin

確認できたら、以降の作業に備え、作成済みのコンテナの停止削除を行います。
| 1 2 3 | $ docker-compose down -v | 
Mediaファイルの設定
staticファイルの設定が完了しましたので、次にmediaファイルの表示設定を行います。
・staticファイル:cssファイル、JSファイル、開発者がプロジェクトに追加した画像など
・mediaファイル:webアプリの利用者が、対象のwebアプリ内で画像やファイルをアップロードして、表示する画像など
settings.pyの編集
staticファイル同様にmediaファイル用のurlとrootを指定します。
| 1 2 3 4 5 6 7 8 9 | ... STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, "static") MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "media") | 
ymlファイルの編集
docker-compose.yml
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | version: "3.7" services:   web:     build: ./django_project     command: gunicorn project.wsgi:application --bind 0.0.0.0:8000     volumes:       - static_volume:/home/app/web/static       - media_volume:/home/app/web/media     expose:       - 8000     env_file:       - ./.env.dev     depends_on:       - db   db:     image: postgres:12.0-alpine     volumes:       - postgres_data:/var/lib/postgresql/data/     env_file:       - ./.env.dev   nginx:     build: ./nginx     volumes:       - static_volume:/home/app/web/static       - media_volume:/home/app/web/media     ports:       - 1317:80     depends_on:       - web volumes:   postgres_data:   static_volume:   media_volume: | 
Dockerファイルの編集
Dockerfile
| 1 2 3 4 5 6 7 8 | ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME RUN mkdir $APP_HOME/static RUN mkdir $APP_HOME/media #追加 WORKDIR $APP_HOME | 
Nginxのconfigファイルの編集
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | upstream project {     server web:8000; } server {     listen 80;     location / {         proxy_pass http://project;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         proxy_set_header Host $host;         proxy_redirect off;     }     location /static/ {         alias /home/app/web/static/;     }     location /media/ {         alias /home/app/web/media/;     } } | 
コンテナを起動し表示確認
使用していたコンテナの停止、削除
| 1 2 3 | $ docker-compose down -v | 
新コンテナの起動
| 1 2 3 | $ docker-compose up -d --build | 
新たな設定でデータベースのマイグレート
| 1 2 3 | $ docker-compose exec web python manage.py migrate --noinpu | 
Djangoプロジェクト内のstatic関係のファイルを、nginxのstaticディレクトリへ移動。
| 1 2 3 | $ docker-compose exec web python manage.py collectstatic --no-input --clear | 
ブラウザで表示を確認します。
http://localhost:1317/
※ポート番号はdocker-compose.prod.ymlで指定した1317番を利用します。

本番環境用ファイル設定:独自ドメインの利用とHTTPS化
ここまでの作業で、Gunicorn、Nginxを利用してサイトへアクセスする方法の動作の設定ができました。
次に、HTTPS化に対応した独自ドメインでのアクセスに対応させます。
今回はLet’s Encryptを利用して対応します。
settings.pyの編集
https化に備えCSRFのセキュリティー強化と、HTTPへリクエストがあった際に、HTTPSへリダイレクトするように以下のコードを追加します。
settings.py
| 1 2 3 | SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") | 
本番環境用docker-compose.ymlファイルの作成
ローカル環境と本番環境でサイトの表示・動作では、ホストの指定の仕方が大きく変わります。
そのため、本番環境用として新たに必要となるファイルを作成します。
以降の方法は有料記事として紹介しています。
【Docker(Docker-Compose)】Python,Djangoの開発・本番環境構築【Postgres,Gunicorn,Nginx利用】
本番環境(リモートサーバー)へのDockerとDockerComposeのインストールと初期設定
こちらの方法は有料記事として紹介しています。
【Docker(Docker-Compose)】Python,Djangoの開発・本番環境構築【Postgres,Gunicorn,Nginx利用】
本番環境でのサイト表示、動作確認①
こちらの方法は有料記事として紹介しています。
【Docker(Docker-Compose)】Python,Djangoの開発・本番環境構築【Postgres,Gunicorn,Nginx利用】
本番環境でのサイト表示、動作確認②
こちらの方法は有料記事として紹介しています。
【Docker(Docker-Compose)】Python,Djangoの開発・本番環境構築【Postgres,Gunicorn,Nginx利用】
開発、本番環境での開発方法
こちらの方法は有料記事として紹介しています。
【Docker(Docker-Compose)】Python,Djangoの開発・本番環境構築【Postgres,Gunicorn,Nginx利用】
以上、Docker(Docker-Compose)を利用しPython,Django,Postgres,Gunicorn,Nginxの開発・本番環境の構築方法を紹介しました。