今回はついにDjangoの立上げを行います。フォルダ配置は前回のDB構築時と同様になりますが、これから編集するdocker-compose.ymlやDockerfileはDjangoプロジェクトのルートフォルダ(manage.pyが置いてある)フォルダと同一フォルダに置いてある想定です。
django #docker-compose.yml, Dockerfile, manage.pyが配置 |-db |-init |-data
Django用PythonのProduction実行環境をDockerで作る
実はDjangoの実行環境をどのようにしてDockerで動かすか非常に悩みました。Docker内にDjangoのソースコードを入れて新しいコンテナを作ってもよいのですが、再構築容易にしたく、可能な限りベースとなるコンテナ+Dockerfileで構築出来るぐらいにとどめたいと考えて、今回は「Djangoが実行できるPython」環境のコンテナを作り、そこにDjangoソースコードを読み込ませて動かすことを考えました。そこで今回はDockerfileを作ります。
Dockerfileの作成
$vi Dockerfile FROM python:3.7.7-slim ENV PYTHONUNBUFFERED 1 RUN mkdir -p /usr/src/app RUN mkdir -p /usr/src/app/static WORKDIR /usr/src/app ADD requirements.txt /usr/src/app/ RUN pip install -r requirements.txt
pythonのバージョンは特に意味はありませんが、3.7.7で動いているアプリだったので3.7.7を選択、しかもslimで問題なかったので、slimとしました。ソースコードを配置させる appフォルダと、staticファイルを配置するstaticを作成 最後にrequirements.txtから必要パッケージをインストールする形になります。
Docker-composeファイルを編集
前回Postgres立上げ用に作成したdocker-compose.ymlファイルに以下を追記します。
version: "2" services: django: restart: always build: . #同フォルダにあるDockerfileを指定 ports: - 32801:8000 command: gunicorn web.wsgi -b 0.0.0.0:8000 environment: - DJANGO_SECRET_KEY=abcdefghijklmnopqrstuvwxyzabl23124 - DATABASE_ENGINE=postgresql - DATABASE_NAME=dj01 - DATABASE_USER=root - DATABASE_PASSWORD=password - DATABASE_HOST=postgres - DATABASE_PORT=5432 volumes: - .:/usr/src/app #カレントディレクトリルートとコンテナ内フォルダをリンク depends_on: - postgres postgres: image: postgres restart: always ports: - "5432:5432" environment: POSTGRES_USER: root POSTGRES_PASSWORD: password hostname: postgres user: root volumes: - ./db/pgsql/init:/docker-entrypoint-initdb.d - ./db/pgsql/data:/var/lib/postgresql/data
enviromentに大量に情報を書いていますが、これはコンテナに渡す環境変数となります。後ほど掲載しますが、Django内の設定ファイルで環境変数を読み出して使用することができますので、ここで設定をしておきます。
#docker-compose up -d
で立ち上げることができます。
DBのマイグレーション
DBのmigrateやスタティックファイルの収集の必要がある場合は
$ sudo docker-compose exec bizcho python manage.py migrate $ sudo docker-compose exec bizcho python manage.py collectstatic
で実行可能です。collectstaticをした場合はファイルの再読み込みの為に
$ sudo docker-compose restart django
をしておいて下さい。
Djangoの設定はどうなるのか?
参考までに私のDjango環境のrequiremnts.txtは以下です。staticfileの配信にwhitenoiceを使用しています。WEBサーバー配下に直接staticファイルを配置しても良いのですが、めんどくさいのでwhitenoiceを使用しました。
$ cat requirements.txt Django==2.2 pytz==2018.9 sqlparse==0.3.0 psycopg2-binary==2.7.7 gunicorn==19.9.0 whitenoise==4.1.2 dj-database-url==0.5.0
また、DBの設定をDjangoに伝えるには、環境編集から読み込みます。settings.pyあたりに以下のようにして読み込んで下さい。この例ではsettings.pyを引き継ぐ、database.pyを使用しているので以下のような記述となりました。db_engineが存在しない場合はsqliteを使用する形になっています。
$ cat settings.py
......
DATABASES = {
"default": database.config()
}
......
$ cat database.py
import os
from django.conf import settings
import dj_database_url
ENGINES = {
"sqlite": "django.db.backends.sqlite3",
"postgresql": "django.db.backends.postgresql_psycopg2",
"mysql": "django.db.backends.mysql",
}
def config():
"""
Detect database environment
"""
# Read env
db_url = os.getenv("DATABASE_URL")
db_service = os.getenv("DATABASE_SERVICE_NAME", "").upper().replace("-", "_")
db_engine = ENGINES.get(os.getenv("DATABASE_ENGINE"))
db_name = os.getenv("DATABASE_NAME")
db_user = os.getenv("DATABASE_USER")
db_password = os.getenv("DATABASE_PASSWORD")
# Not Appserver service env
if db_engine:
db_host = os.getenv("DATABASE_HOST")
db_port = os.getenv("DATABASE_PORT")
# Local and Test env
else:
db_engine = ENGINES["sqlite"]
db_name = os.path.join(settings.BASE_DIR, "db/db.sqlite3")
db_host = os.getenv("DATABASE_HOST")
db_port = os.getenv("DATABASE_PORT")
return {
"ENGINE": db_engine,
"NAME": db_name,
"USER": db_user,
"PASSWORD": db_password,
"HOST": db_host,
"PORT": db_port,
}
以上でIPアドレス:32801でアクセス出来ると思います。SSL化についてはWordpress同様にNGINXを使用するので、NGINXのコンフィグはこちらを参照して下さい。