はじめに
Docker (docker-compose)と Linux に標準で搭載されているシェルを組み合せて、
下記 概要に挙げた Django 環境を 1コマンドで即座に立ち上げるためのコードとその解説です.
本記事の内容は、Zenn で書籍として販売している内容と同一です.
Zenn でも書籍の内容は全て無料公開しています.
次の順でコードを作成してください.
動作するコードが作成できるように可能な限り注意を払って執筆しました.
・[01] デフォルト環境 runserver + SQLite3 の構築
・[02] SQLite3 を PostgreSQL へ置き換える
・[03] Django アプリの立ち上げもさせる
・[04] jwilder/dockerize を使ってセットアップ処理を改良する
・本記事の内容
概要
今回は下図・下表の環境を構築する. (前章からの変更点は🔥である)
より具体的な変更点としては次である.
・アプリサーバを runserver から gunicorn に置き換える
概念図
図を簡単にするために、jwilder/dockerize の線は省略している.
コンテナ内の構成
項目 | 値 | 補足 |
---|---|---|
Python | バージョン3.8.3 |
python:3.8.3-slim-buster を使う |
Django | バージョン3.0.7 | |
アプリサーバ | gunicorn🔥 | 8000番ポートを使用する |
データベース | PostgreSQL 12.0 | ポートは次の通り ・ホスト側「53432」 ・コンテナ側「5432」 管理者アカウントは次の通り ・アカウント「 admin 」・パスワード「 admin 」 |
settings.py | ホスト上の ./web/assets/settings.py が、コンテナ内に /usr/src/app/config/settings.py として配置される. |
|
Django admin ページ | 管理者アカウントは次の通り ・アカウント「 admin 」・パスワード「 admin 」 |
|
アプリケーション | アプリ名「shop」 | 各ユーザが使用したいアプリに置き換えてほしい |
コンテナ起動確認ツール | jwilder/dockerize |
セットアップコード
全文
前章で作成したコードに対して、本記事の内容を適用してください.
web/assets/settings.py より、「DEBUG = True」と「DEBUG = False」の両パターンでセットアップできることを確認している.
ファイル構成
上記 GitHub からコードを取得してきた直後の構成である.
前章から変更が生じたファイルには🏷️を、新規作成については🆕を付与している.
.
|-- db
| `-- Dockerfile
|-- docker-compose.yml 🏷️
|-- setupapp.sh 🏷️........... セットアップスクリプト
`-- web
|-- Dockerfile
`-- assets .............. コンテナへコピーされるデータ
|-- entrypoint.sh
|-- requirements.txt 🏷️
|-- sample
| `-- shop
| |-- admin.py
| `-- models.py
`-- settings.py
解説
docker-compose.yml
・runserver の代わりに gunicorn を起動させる.
・./config/wsgi.py
というファイル構成のため、引数を「config.wsgi:application
」としている.
・gunicorn は 8プロセスで 8000番ポートで待ち受けする.
・gunicorn の ログを /usr/src/app/log/gunicorn.log として出力する.
--- docker-compose.yml.ORIG
+++ docker-compose.yml
@@ -6,7 +6,12 @@
image: mydjango307
container_name: mydjango307
command: >
- bash -c 'python manage.py runserver 0.0.0.0:8000'
+ bash -c '
+ gunicorn config.wsgi:application \
+ --workers 8 \
+ --access-logfile /usr/src/app/log/gunicorn.log \
+ --bind 0.0.0.0:8000
+ '
volumes:
- ./web/app/:/usr/src/app/
ports:
setupapp.sh
■ gunicorn のログ出力先として ./web/app/log/ を作成する.
■ ./web/app/log/ に対して書き込みができるように権限を付与する.
■ 「jwilder/dockerize
」コンテナから Django コンテナに対して疎通確認をする.
・リクエスト先を「Django admin ページ」すなわち http://localhost:53000/admin
に変更する.
・前章のように "ルートパス" だと「DEBUG = False」時に疎通できず に「404」(下表🛑)と判断されてしまう.
settings.py の DEBUG の値 | 問合せ先 URL | レスポンス(HTTPステータスコード) |
---|---|---|
True | http://localhost:53000 |
200 |
False | http://localhost:53000 |
404🛑 |
--- setupapp.sh.ORIG
+++ setupapp.sh
@@ -13,9 +13,13 @@
# 必須ディレクトリを作成する
sudo mkdir -p web/app
+sudo mkdir -p web/app/log
sudo mkdir -p db/data
sudo mkdir -p db/init
+# 必要な権限を付与しておく
+sudo chmod 777 web/app/log
+
# entrypoint.sh を配置する
sudo cp ./web/assets/entrypoint.sh ./web/app/
# settings.py をコンテナ内に .settings.py として配置する
@@ -31,7 +35,7 @@
set -e
# 0.5秒周期で Django と PostgreSQL コンテナから応答があるまで待機する. (上限 1分間)
-docker-compose run --rm dockerize sh -c 'dockerize -wait http://web:8000 -wait tcp://db:5432 -timeout 1m -wait-retry-interval 0.5s'
+docker-compose run --rm dockerize sh -c 'dockerize -wait http://web:8000/admin -wait tcp://db:5432 -timeout 1m -wait-retry-interval 0.5s'
# jwilder/dockerize の処理が済んだので、set -e を無効にする.
set +e
web/assets/requirements.txt
・pip で gunicorn
をインストールするように定義を追加する.
--- web/assets/requirements.txt.ORIG
+++ web/assets/requirements.txt
@@ -4,3 +4,4 @@
djangorestframework==3.11.0
psycopg2==2.8.5
psycopg2-binary==2.8.5
+gunicorn==20.0.4
セットアップ方法
次の通りコマンドを実行する.
$ ./setupapp.sh
セットアップ後
ファイル構成
$ tree . --charset=c -a
.
|-- db
| |-- Dockerfile
| |-- data [error opening dir]
| `-- init
|-- docker-compose.yml
|-- setupapp.sh
`-- web
|-- Dockerfile
|-- app
| |-- .settings.py
| |-- config
| | |-- __init__.py
| | |-- asgi.py
| | |-- settings.py
| | |-- urls.py
| | `-- wsgi.py
| |-- entrypoint.sh
| |-- log
| | `-- gunicorn.log
| |-- manage.py
| `-- shop
| |-- __init__.py
| |-- admin.py
| |-- apps.py
| |-- migrations
| | |-- 0001_initial.py
| | `-- __init__.py
| |-- models.py
| |-- tests.py
| `-- views.py
`-- assets
|-- entrypoint.sh
|-- requirements.txt
|-- sample
| `-- shop
| |-- admin.py
| `-- models.py
`-- settings.py
動作確認方法
次の点を確認すれば良い.
✔ Dockerコンテナが次のように起動していること
コンテナ「jwilder_dockerize
」は使い捨て型なので、Exit 2 は意図した結果であり問題無し.
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
jwilder_dockerize dockerize --help Exit 2
mydjango307 /usr/src/app/entrypoint.sh ... Up 0.0.0.0:8000->8000/tcp
mypostgres12 docker-entrypoint.sh postgres Up 0.0.0.0:53432->5432/tcp
✔ http://localhost:8000 にアクセスして次の画面が表示されること.
このとき、背景画像が適用されておらず "まっしろ" になっていること
✔ http://localhost:8000/admin にアクセスして、アカウント「admin
」、パスワード「admin
」でログインできること.
このとき、背景画像が適用されておらず "まっしろ" になっていること
✔ Djangoコンテナのログに Gunicorn が起動したログが表示されていること
・53000番ポートを公開していること(下図🛑)
・計8個のプロセスが稼働していること(下図🦄)
$ docker-compose logs web | tail -n 11
mydjango307 | [2021-07-11 03:16:59 +0900] [1] [INFO] Starting gunicorn 20.0.4
mydjango307🛑| [2021-07-11 03:16:59 +0900] [1] [INFO] Listening at: http://0.0.0.0:53000 (1)
mydjango307 | [2021-07-11 03:16:59 +0900] [1] [INFO] Using worker: sync
mydjango307 | [2021-07-11 03:16:59 +0900] [9] [INFO] Booting worker with pid: 9
mydjango307🦄| [2021-07-11 03:16:59 +0900] [10] [INFO] Booting worker with pid: 10
mydjango307🦄| [2021-07-11 03:16:59 +0900] [11] [INFO] Booting worker with pid: 11
mydjango307🦄| [2021-07-11 03:17:00 +0900] [12] [INFO] Booting worker with pid: 12
mydjango307🦄| [2021-07-11 03:17:00 +0900] [13] [INFO] Booting worker with pid: 13
mydjango307🦄| [2021-07-11 03:17:00 +0900] [14] [INFO] Booting worker with pid: 14
mydjango307🦄| [2021-07-11 03:17:00 +0900] [15] [INFO] Booting worker with pid: 15
mydjango307🦄| [2021-07-11 03:17:00 +0900] [16] [INFO] Booting worker with pid: 16
以上.