🐳

docker-composeでDjango開発環境を構築する

2020/10/24に公開
2

はじめに

docker-composeを使って単一ホストにサービス別コンテナをたて、DjangoによるWebアプリケーション開発環境を構築してみる。ホストはローカル(AWS EC2でも可)を想定している。

docker-composeは単一ホストでしか使用できず、状況に応じて動的リソースの割り当ての必要が生じる可能性のあるプロダクション環境には使用が推奨されていない。別途AWS ECS・EKSなどのコンテナ基盤を使うべきだが、それに関しては本記事には記載しない。

本記事の対象読者としては以下を想定している。

  • pipenvを使った開発をしたことがある
  • Djangoの公式チュートリアルは実施済み。
  • Docker、docker-composeの基本的な知識は持っている。

目指すゴール

key value
Host Docker、docker-composeをインストールする。システムに必要なすべてのコンテナを格納する。ローカル環境/AWS EC2等を想定。
Container: web server Gunicorn(WSGI HTTP Server)のリバースプロキシとして機能し、クライアントリクエストを処理する。ホストの1337番をコンテナの80番にポートフォワーディング。
Container: application server Gunicorn(WSGI HTTP Server)上でDjangoアプリケーションを動かす。コンテナの8000番ポートをLISTEN状態にする。ホスト側の任意のフォルダをコンテナ側にマウントし、静的ファイルとメディアファイルの永続化を実現する。
Container: db server PostgreSQLを動かす。コンテナの5432番ポートをLISTEN状態にする。ホスト側の任意のフォルダをコンテナ側にマウントし、DBデータの永続化を実現する。

ディレクトリ構成

django-on-docker
├── .env.development
├── docker-compose.development.yml
├── app                             <- application server container source
│   ├── Dockerfile.development
│   ├── entrypoint.development.sh
│   ├── Pipfile
│   ├── Pipfile.lock
│   ├── manage.py
│   ├── app                         <- Django project setting dir
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── uploads                     <- Django file upload app dir
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       │   └── __init__.py
│       ├── models.py
│       ├── templates
│       │   └── upload.html
│       ├── tests.py
│       └── views.py
└── nginx                           <- web server container source
    ├── Dockerfile.development
    └── nginx.development.conf

参考

使用する技術

  • Docker 19.03.x
  • docker-compose 1.27.x
  • Python 3.8.x
  • Django 3.x
  • Gunicorn 20.0.x
  • Nginx 1.19.x
  • PostgreSQL 12.x
  • pipenv version 2018.11.26

プロジェクトのセットアップ

開発を行う環境の任意のディレクトリにプロジェクトを作成する。
パッケージ管理と仮想環境構築は pipenv で行う。

$ mkdir django-on-docker && cd django-on-docker
$ mkdir app && cd app
$ pipenv --python 3.8
$ ls
Pipfile

仮想環境に入って必要なパッケージをインストールする。
/app ディレクトリで以下を実行。

$ pipenv shell
(app)$ pipenv install django gunicorn psycopg2-binary
(app)$ ls
Pipfile		Pipfile.lock

Djangoプロジェクトを作成する。
/app ディレクトリで以下を実行。

(app)$ django-admin.py startproject app .

マイグレーションファイルの生成と、生成されたマイグレーションファイルからDjangoモデルのDBテーブルを作成。
/app/ ディレクトリで以下を実行。

(app)$ python manage.py makemigrations
(app)$ python manage.py migrate

Django付属の開発サーバーを起動し、サイトにアクセス。
/app/ ディレクトリで以下を実行。

(app) $ python manage.py runserver
...
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
...

http://localhost:8000/ にアクセスすると、Djangoサイトのwelcomeページが表示される。

Django付属の開発サーバーを使うと、Dockerやwebサーバ(Nginx)、アプリケーションサーバ(Gunicorn/uWSGI)を使用しなくても開発が可能である。その場合、データベースは接続設定すればローカルにインストールしたPostgreSQLも使えるが、初期設定ではSQLite3が使われる。

マイグレーションを実行済みであれば appdb.sqlite3 というデータファイルが生成されているはずなので、一旦 Ctrl+C で開発サーバを停止し、SQLite3のデータファイルを確認してみる。

(app) $ ls
Pipfile		Pipfile.lock	app		db.sqlite3	manage.py

db.sqlite3 ファイルを削除して再度マイグレーションをやり直せばデータのリセットが可能である。

本記事では、一歩進んでよりプロダクション環境のシステム構成に近づけるため、役割別の複数のコンテナを立てながら開発できる環境の構築を目指す。
アプリデータは別途たてるDBコンテナに登録するため、不要となるdb.sqlite3を削除しておく。

現状のディレクトリ構成:

$ tree
.
└── app
    ├── Pipfile
    ├── Pipfile.lock
    ├── manage.py
    └── app
        ├── __init__.py
        ├── asgi.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

Dockerの導入

applicationサーバのコンテナを構築するDockerfile

システムの中心となるapplicationサーバのコンテナのDockerfileを/app/Dockerfile.developmentに作成する。Dockerfileは環境別に用意する必要があるため、ファイル名にサフィックスを付けている。

# pull official base image
FROM python:3.8.2-alpine

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# create Django directory for the app user
ENV APP_HOME=/usr/src/app
RUN mkdir -p $APP_HOME && \
    mkdir $APP_HOME/staticfiles && \
    mkdir $APP_HOME/mediafiles

# create the app user
RUN addgroup -S app && adduser -S app -G app

# set work directory
WORKDIR $APP_HOME

# install dependencies
COPY ./Pipfile .
COPY ./Pipfile.lock .
RUN apk update && \
    apk add postgresql-dev gcc python3-dev musl-dev libpq && \
    pip install --upgrade pip && \
    pip install pipenv && \
    pipenv install --dev --system

# copy entrypoint shell file
COPY ./entrypoint.development.sh $APP_HOME

# copy project
COPY . $APP_HOME

# chown all the files to the app user
RUN chown -R app:app $APP_HOME

# change to the app user
USER app

# run entrypoint shell file
ENTRYPOINT ["/usr/src/app/entrypoint.development.sh"]

Dockerイメージには、デプロイ速度向上や不要プロセスの発生防止・メモリ節約という理由によって不要なものを含めないことが推奨されている。そのため、イメージには軽量なPythonのalpineを使用する。
本記事では扱わないが、イメージの軽量化にはビルド環境とランタイム環境を分離できるDockerのマルチステージビルドなどの方法も存在する。

イメージレイヤーの増加に比例してイメージサイズも増加するため、イメージレイヤーを追加するRUNCOPYADD コマンドの使用には注意する。無駄に増やさないようにするには、RUNコマンドは&&でつなげる、レイヤーキャッシュを有効活用するために変更がありそうな記述を後方に設定するなどの工夫が必要になる。

また、Dockerはデフォルトではコンテナプロセスをコンテナ内のrootユーザとして実行する。この状態では、もしコンテナへの攻撃者がコンテナから抜け出すことに成功した場合にホストのrootにアクセスできてしまう。そのため、コンテナ内のデフォルトユーザを新規作成し、そちらで操作するように変更している。

entrypoint.shの導入

Dockerはコンテナ起動時に実行するコマンドを一つだけ指定できる。これを利用すれば、シェルファイルに任意の処理を記載してENTRYPOINTCMDコマンドで実行指定することにより、コンテナ起動時に任意の処理をまとめて実行させることができる。

ここでは、Dockerfile.developmentENTRYPOINTコマンドで実行する/app/entrypoint.development.sh を作成する。

#!/bin/sh

if ["$DATABASE" = "postgres"
then
    echo "Waiting for postgres..."

    while ! nc -z $DB_HOST $DB_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

# ex. Here is a list of commands you want to run after PostgreSQL is started.
# python manage.py flush --no-input
# python manage.py migrate
# python manage.py init_data

exec "$@"

(コメントアウトしているが)上記は、PostgreSQLの起動が確認できた後にDBデータ初期化とマイグレーションを実行し、新しい初期データを登録するDjangoのカスタムコマンドを実行している例である(init_dataはカスタム作成コマンド)。

ただしここに記載するコマンドはコンテナの起動時に都度実行されるので、それを考えた上で実行コマンドを選ぶ必要がある。例えば、docker-compose restartの実行ごとのデータ初期化は不要(データの永続化をしたい)のであれば上記コマンドの記載は不要である。

docker-composeが実行できるようにパーミッションを変更しておく。

(app) $ chmod +x entrypoint.development.sh

現状のディレクトリ構成:

$ tree
.
└── app
    ├── Dockerfile.development
    ├── entrypoint.development.sh
    ├── Pipfile
    ├── Pipfile.lock
    ├── manage.py
    └── app
        ├── __init__.py
        ├── asgi.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

webサーバのコンテナを構築するDockerfile

次に、Nginxのコンテナを追加する。これはapplicationサーバであるGunicornのリバースプロキシとして機能し、クライアントリクエストを処理し、静的ファイルを提供する。

/nginx/nginx.development.conf

upstream my_app {
    server app:8000;
}

server {

    listen 80;

    location / {
        proxy_pass http://my_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

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

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

リダイレクト設定

アクセス元 リダイレクト先
webサーバコンテナの80番ポートで受け付けたhttpリクエスト applicationサーバのコンテナの8000番ポート
/staticfiles/ へのリクエスト デザイン関連の静的ファイルが格納されている/usr/src/app/staticfiles/
/mediafiles/ へのリクエスト アップロードファイルが格納されている/usr/src/app/mediafiles/

applicationサーバの/usr/src/app/staticfiles//usr/src/app/mediafiles/はapplicationサーバのコンテナのDockerfileで作成している。
後述するDjangoの設定により、静的ファイルとアップロードファイルは上記ディレクトリに格納される。

/nginx/Dockerfile.development

FROM nginx:1.19.0-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.development.conf /etc/nginx/conf.d

デフォルト設定ファイルを削除し、ホストの/nginx/nginx.development.confをコンテナにCOPYして使う。

現状のディレクトリ構成:

$ tree
.
├── app
│   ├── Dockerfile.development
│   ├── entrypoint.development.sh
│   ├── Pipfile
│   ├── Pipfile.lock
│   ├── manage.py
│   └── app
│       ├── __init__.py
│       ├── asgi.py
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
└── nginx
    ├── Dockerfile.development
    └── nginx.development.conf

DBサーバのコンテナを構築するDockerfile

イメージはDockerHubのpostgresをそのまま使用するため、Dockerfileは不要。

環境変数の定義

Dockerの各コンテナで参照する環境変数を一元管理するために、環境別の専用の設定ファイルを定義する。
プロジェクトルートの直下に/.env.developmentファイルを作成する。環境変数は開発環境とプロダクション環境では値も種類も異なる可能性がある。そのため、読み込む環境をファイル名で識別できるように開発環境を表現するサフィックス.developmentという値を付与しておく。
ここで定義された環境変数は、後述のdocker-compose設定ファイルに指定することによって各コンテナから参照できるようになる。

#########
# for app
#########

# 0:not debug mode / 1: debug mode
DEBUG=0
# Django unique secret key value
SECRET_KEY=foo
# Host names to allow access to django apps
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
# Database process name
DATABASE=postgres

# database connection settings
DB_ENGINE=django.db.backends.postgresql
DB_NAME=app
DB_USER=app
DB_PASSWORD=password
DB_HOST=db
DB_PORT=5432

#########
# for db
#########

POSTGRES_USER=app
POSTGRES_PASSWORD=password
POSTGRES_DB=app

Djangoの基本設定

/app/app/settings.py を修正、追記する。
/.env.development で設定している環境変数を参照していることに注目する。

import os

DEBUG = int(os.environ.get("DEBUG", default=0))
SECRET_KEY = os.environ.get("SECRET_KEY", "foo")
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(" ")

DATABASES = {
    "default": {
        "ENGINE": os.environ.get("DB_ENGINE"),
        "NAME": os.environ.get("DB_NAME"),
        "USER": os.environ.get("DB_USER"),
        "PASSWORD": os.environ.get("DB_PASSWORD"),
        "HOST": os.environ.get("DB_HOST"),
        "PORT": os.environ.get("DB_PORT"),
    }
}

# set static files directory and url path
STATIC_URL = '/staticfiles/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

# set upload files directory and url path
MEDIA_URL = "/mediafiles/"
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")

DjangoのURL設定

/app/app/urls.py を以下に修正する。

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
]

if bool(settings.DEBUG):
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)

docker-composeの設定

/docker-compose.development.ymlに以下を記載する。

version: "3.7"

services:
  app:
    build:
      context: ./app
      dockerfile: Dockerfile.development
    command: gunicorn app.wsgi:application --bind 0.0.0.0:8000
    working_dir: /usr/src/app/
    volumes:
      - ./app:/usr/src/app
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.development
    depends_on:
      - db
    networks:
      - front
      - back
  db:
    image: postgres:12.0-alpine
    volumes:
      - db_data:/var/lib/postgresql/data/
    env_file:
      - ./.env.development
    networks:
      - back
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile.development
    volumes:
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    ports:
      - 1337:80
    depends_on:
      - app
    networks:
      - front

volumes:
  db_data:
  static_volume:
  media_volume:

networks:
  front:
    external: false
  back:
    external: false

いままで作成してきたDockerファイルを各サービスに指定し、ポートやボリューム、ネットワークの設定をしている。以下詳細。

  • service.app
    • buildコンテキストとDockerfileの指定。
    • WSGIサーバの起動。
    • 静的ファイル・メディアファイルの永続化のため、ホスト側のvolumes設定ディレクトリをコンテナにマウントする。
    • 開発コードをコンテナ内のコードと同期させるためのボリューム設定。
    • applicationサーバコンテナを8000番ポートで受け付け。
    • 環境変数ファイルの読み込み。
    • service.dbコンテナを起動させてからservice.appコンテナを起動。ただし、service.dbの準備が整うまでは待たない。そのため、上記で記載したようにentorypoint.shでPostgreSQLの準備が整うまで待ってから実行する処理を記載する。
    • frontbackの両方のネットワークに属する。
  • service.nginx
    • buildコンテキストとDockerfileの指定。
    • 静的ファイル・メディアファイルの永続化のため、ホスト側のvolumes設定ディレクトリをコンテナにマウントする。
    • httpリクエストを1337ポートで受け付け、webサーバコンテナを80番ポートで受け付け。
    • service.appコンテナを起動させてからservice.nginxコンテナを起動。
    • frontネットワークに属する。
  • service.db
    • buildイメージにDockerHubのpostgresを指定。
    • DBデータの永続化のため、ホスト側のvolumes設定ディレクトリをコンテナにマウントする。
    • 環境変数ファイルの読み込み。
    • backネットワークに属する。
  • volumes
    • ホスト側にボリューム領域を作成する。

volumeについての補足
作成されたvolumeは以下で確認できる。

$ docker volume ls
DRIVER              VOLUME NAME
local               django-on-docker_db_data
local               django-on-docker_media_volume
local               django-on-docker_static_volume

$ docker volume inspect django-on-docker_db_data
[
    {
        "CreatedAt": "2020-10-24T04:20:27Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "django-on-docker",
            "com.docker.compose.version": "1.27.4",
            "com.docker.compose.volume": "db_data"
        },
        "Mountpoint": "/var/lib/docker/volumes/django-on-docker_db_data/_data",
        "Name": "django-on-docker_db_data",
        "Options": null,
        "Scope": "local"
    }
]

ただし、基本的にはホスト側のボリュームがどこに作成されているのかは気にする必要はない。
ボリュームのデータは永続化されているため、docker-compose stopで各コンテナを停止しても消えることはない。しかし、docker-compose downでイメージ、コンテナ、ボリューム、ネットワークを削除すると消えてしまうため注意。

これで、一通りの準備が整った状態となる。

現状のディレクトリ構成:

$ tree
.
├── .env.development
├── docker-compose.development.yml
├── app
│   ├── Dockerfile.development
│   ├── entrypoint.development.sh
│   ├── Pipfile
│   ├── Pipfile.lock
│   ├── manage.py
│   └── app
│       ├── __init__.py
│       ├── asgi.py
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
└── nginx
    ├── Dockerfile.development
    └── nginx.development.conf

docker-composeを実行してシステムを起動する

最初に、プロジェクトのルートにてシステムの初期化に必要なコマンドを実行する。
以下のコマンドは、イメージのビルド時のみに実行する。

イメージをビルドし、各コンテナを起動

$ docker-compose -f docker-compose.development.yml up -d --build
...

$ docker-compose -f docker-compose.development.yml ps -a
          Name                        Command               State          Ports
----------------------------------------------------------------------------------------
django-on-docker_app_1     /usr/src/app/entrypoint.de ...   Up      8000/tcp
django-on-docker_db_1      docker-entrypoint.sh postgres    Up      5432/tcp
django-on-docker_nginx_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:1337->80/tcp

コンテナが3つ起動していることが確認できる。

データの初期化 → マイグレーションファイル生成 → DBテーブルの生成

$ docker-compose -f docker-compose.development.yml exec app python manage.py flush --no-input
$ docker-compose -f docker-compose.development.yml exec app python manage.py makemigrations
$ docker-compose -f docker-compose.development.yml exec app python manage.py migrate

静的ファイルをapplicationサーバコンテナの/usr/src/app/staticfiles/以下に配置

$ docker-compose -f docker-compose.development.yml exec app python manage.py collectstatic --no-input --clear

Django管理者ユーザの登録

$ docker-compose -f docker-compose.development.yml exec app python manage.py createsuperuser
Username (leave blank to use 'app'): [admin user name]
Email address: [admin user email]
Password: [admin user login password]
Password (again): 
Superuser created successfully.

http://localhost:1337/admin/login/ にアクセスしてみると、Django管理サイトログイン画面が表示される。
上記で登録したDjango管理者ユーザのアカウントでログインしてみよう。

その他コマンド

各コンテナを一時停止させる。開発を一時的に停止させるときに使用。

$ docker-compose -f docker-compose.development.yml stop

停止させた各コンテナを起動させる。開発を再開させるときに使用。

$ docker-compose -f docker-compose.development.yml start

各コンテナをリスタートさせる。stop → start と同じ。

$ docker-compose -f docker-compose.development.yml restart

イメージ、コンテナ、ボリューム、ネットワークを削除する。イメージの再ビルドが必要となった時や、プロジェクトの削除時に使用。

$ docker-compose -f docker-compose.development.yml down

指定のコンテナのみ再起動する。開発でコードの更新が発生した場合に使用。

$ docker container restart django-on-docker_app_1

データの永続化を確認する

ファイルをアップロードできるアプリケーションをDjangoに追加し、コンテナのリスタートでデータの永続化が実現出来ているかを確認する。

上記で作成してきたイメージ・コンテナ・ボリューム・ネットワークを削除しておく。

$ docker-compose -f docker-compose.development.yml down --rmi all --volumes --remove-orphans

Djangoにuploadsアプリを追加する

/app ディレクトリで以下を実行。

$ cd app
$ pipenv shell
(app)$ python manage.py startapp uploads
$ tree
.
├── .env.development
├── docker-compose.development.yml
├── app
│   ├── Dockerfile.development
│   ├── entrypoint.development.sh
│   ├── Pipfile
│   ├── Pipfile.lock
│   ├── manage.py
│   ├── app
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── uploads
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       │   └── __init__.py
│       ├── models.py
│       ├── tests.py
│       └── views.py
└── nginx
    ├── Dockerfile.development
    └── nginx.development.conf

/app/app/settings.pyの修正。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'uploads.apps.UploadsConfig',  <- append
]

/app/app/urls.pyの修正。

from uploads.views import image_upload               <- append

urlpatterns = [
    path("uploads/", image_upload, name="uploads"),  <- append
    path('admin/', admin.site.urls),
]

/app/uploads/views.pyの修正。

from django.shortcuts import render
from django.core.files.storage import FileSystemStorage

def image_upload(request):
    if request.method == "POST" and request.FILES["image_file"]:
        image_file = request.FILES["image_file"]
        fs = FileSystemStorage()
        filename = fs.save(image_file.name, image_file)
        image_url = fs.url(filename)
        print(image_url)
        return render(request, "upload.html", {
            "image_url": image_url
        })
    return render(request, "upload.html")

/app/uploads/templates/upload.htmlの追加。

{% block content %}

  <form action="{% url "uploads" %}" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="image_file">
    <input type="submit" value="submit" />
  </form>

  {% if image_url %}
    <p>File uploaded at: <a href="{{ image_url }}">{{ image_url }}</a></p>
  {% endif %}

{% endblock %}

docker-composeを実行してシステムを起動、アップロードファイルの永続化を確認

上記と同様に以下を順次実行する。

$ docker-compose -f docker-compose.development.yml up -d --build
$ docker-compose -f docker-compose.development.yml exec app python manage.py flush --no-input
$ docker-compose -f docker-compose.development.yml exec app python manage.py makemigrations
$ docker-compose -f docker-compose.development.yml exec app python manage.py migrate
$ docker-compose -f docker-compose.development.yml exec app python manage.py collectstatic --no-input --clear
$ docker-compose -f docker-compose.development.yml exec app python manage.py createsuperuser

http://localhost:1337/uploads/ にアクセスしてみると、ファイルアップロード画面が表示される。

ファイルを選択肢、アップロードしてみよう。

表示されたリンクには、アップロードした画像ファイルが存在する。リンクをクリックし、ブラウザで画像を表示させてみる。

コンテナにアップロードファイルが存在することを確認する。

$ docker exec -it django-on-docker_app_1 ls ./mediafiles
Screen Shot 2020-10-24 at 14.53.45.png

コンテナを再起動させ、アップロードファイルの永続化を確認してみる。

$ docker-compose -f docker-compose.development.yml restart
Restarting django-on-docker_nginx_1 ... done
Restarting django-on-docker_app_1   ... done
Restarting django-on-docker_db_1    ... done
$ docker exec -it django-on-docker_app_1 ls ./mediafiles
Screen Shot 2020-10-24 at 14.53.45.png

まとめ

本記事では、単一ホストにwebサーバ・applicationサーバ・DBサーバそれぞれ別のコンテナを起動して連携させ、開発環境を構築してみた。プロダクション環境のデプロイは、ここで実施した作業の他に考えねばならないことが山ほどある。

  • SSLの設定
  • オートスケールの設定
  • DBマイグレーション実行環境の構築
  • CI/CDの設定
  • 静的ファイルをS3などの外部ストレージに配置
  • インフラコードの自動化

それについてはまた別途記事を書く予定。

本記事のsourceはこちら(https://github.com/dsonoda/django-on-docker)にあるので、気軽にこの内容を試してみたい方はReadmeのUsageをご確認ください。おそらく5分もかからずに再現できると思います。
もし気に入っていただけたらGitHubスターを押して頂けると嬉しいです。

Discussion