はじめに
Docker (docker-compose)と Linux に標準で搭載されているシェルを組み合せて、
下記 概要に挙げた Django 環境を 1コマンドで即座に立ち上げるためのコードとその解説です.
本記事の内容は、Zenn で書籍として販売している内容と同一です.
Zenn でも書籍の内容は全て無料公開しています.
次の順でコードを作成してください.
動作するコードが作成できるように可能な限り注意を払って執筆しました.
・[01] デフォルト環境 runserver + SQLite3 の構築
・本記事の内容
概要
今回は下図・下表の環境を構築する. (前章からの変更点は🔥である)
具体的には次の通り.
・SQLite3 ではなく、PostgreSQL を使うようにする
概念図
コンテナ内の構成
項目 | 値 | 補足 |
---|---|---|
Python | バージョン3.8.3 |
python:3.8.3-slim-buster を使う |
Django | バージョン3.0.7 | |
アプリサーバ | runserver | 8000番ポートを使用する |
データベース | PostgreSQL 12.0🔥 | ポートは次の通り ・ホスト側「53432」 ・コンテナ側「5432」 管理者アカウントは次の通り ・アカウント「 admin 」・パスワード「 admin 」 |
settings.py | 「DATABASE 」の設定を PostgreSQL に変える. 🔥 |
ホスト上の ./web/assets/settings.py が、コンテナ内に /usr/src/app/config/settings.py として配置される. |
Django admin ページ | 管理者アカウントは次の通り ・アカウント「 admin 」・パスワード「 admin 」 |
セットアップコード
全文
前章で作成したコードに対して、本記事の内容を適用してください.
web/assets/settings.py より、「DEBUG = True」のみセットアップできることを確認している.
ファイル構成
上記 GitHub からコードを取得してきた直後の構成である.
前章から変更が生じたファイルには🏷️を、新規作成については🆕を付与している.
$ tree . --charset=c -a
.
|-- db 🆕
| `-- Dockerfile 🆕
|-- docker-compose.yml 🏷️
|-- setupapp.sh 🏷️........... セットアップスクリプト
`-- web
|-- Dockerfile 🏷️
`-- assets .............. コンテナへコピーされるデータ
|-- entrypoint.sh 🏷️
|-- requirements.txt 🏷️
`-- settings.py 🏷️
解説
db/Dockerfile
新規作成.
特筆すべき事項なし.
FROM postgres:12-alpine
ENV LANG ja_JP.utf8
## プロキシサーバを使う場合
# ENV http_proxy="http://proxy.co.jp:8080"
# ENV https_proxy="http://proxy.co.jp:8080"
# 時刻を日本に合わせる
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
setupapp.sh
前章からの変化点は次の通り.
・PostgreSQL 用の永続化ボリュームとして次を作成する.
./db/data
./db/init
・PostgreSQL を使用するよう記述した settings.py をコンテナ内に配置する
以下、前回からの差分である.
--- ./setupapp.sh.ORIG
+++ ./setupapp.sh
@@ -2,6 +2,8 @@
@@ -2,6 +2,8 @@
# 旧データを削除する
sudo rm -rf web/app
+sudo rm -rf db/data
+sudo rm -rf db/init
# docker-compose.yml で書かれたサービスのコンテナ、イメージ、ネットワークを削除する
docker-compose down --rmi all --volumes
@@ -11,9 +13,13 @@
# 必須ディレクトリを作成する
sudo mkdir -p web/app
+sudo mkdir -p db/data
+sudo mkdir -p db/init
# entrypoint.sh を配置する
sudo cp ./web/assets/entrypoint.sh ./web/app/
+# settings.py をコンテナ内に .settings.py として配置する
+sudo cp ./web/assets/settings.py ./web/app/.settings.py
# Dockerイメージビルドを行う.
docker-compose build
@@ -31,6 +37,9 @@
}
# コンテナ内でのマイグレーション終了を待つ.
+# なお、ここで 待機時間を取らないと次のエラーが出現してしまう.
+#「django.db.utils.IntegrityError: duplicate key value violates unique constraint "pg_type_typname_nsp_index"」
+# [参考] https://www.odin.hyork.net/write/write0206.html
sleep 4
# 「Django管理サイト」の管理者アカウントを作成する. (ID「admin」, PW「admin」とする)
docker-compose.yml
前章からの変化点は次の通り.
・ポート (ホスト側 : コンテナ側) = (53432 : 5432) とする.
・PostgreSQL の管理者アカウント「admin
」、パスワード「admin
」とする
--- docker-compose.yml.ORIG
+++ docker-compose.yml
@@ -11,3 +11,19 @@
- ./web/app/:/usr/src/app/
ports:
- 8000:8000
+ depends_on:
+ - db
+ db:
+ build: ./db
+ image: postgres:12
+ container_name: mypostgres12
+ volumes:
+ - ./db/data:/data
+ - ./db/init:/docker-entrypoint-initdb.d/
+ ports:
+ - "53432:5432"
+ environment:
+ POSTGRES_DB: 'django307'
+ POSTGRES_USER: 'admin'
+ POSTGRES_PASSWORD: 'admin'
+ PGDATA: '/data'
web/Dockerfile
前章からの変化点は次の通り.
・build-essential は requirements.txt に追加した psycopg2 のインストールで必要である
・libpq-dev は Python から PostgreSQL を操作するために必要である
--- web/Dockerfile.ORIG
+++ web/Dockerfile
@@ -11,6 +11,10 @@
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
+RUN apt-get update
+RUN apt-get install -y build-essential
+RUN apt-get install -y libpq-dev
+
# 時刻を日本に合わせる
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
web/assets/entrypoint.sh
前章からの変化点は次の通り.
・事前に PostgreSQL の設定を記述しておいた settings.py を、コンテナ内の /usr/src/app/config/settings.py として配置する
--- web/assets/entrypoint.sh.ORIG
+++ web/assets/entrypoint.sh
@@ -4,6 +4,8 @@
test ! -f manage.py && {
# プロジェクトを作成する (config/ と manage.py が作成される)
django-admin.py startproject config .
+ # 事前に用意しておいた PostgreSQL 対応の settings.py に差し替える
+ cp -f .settings.py config/settings.py
# マイグレーションを実施する
python manage.py makemigrations
python manage.py migrate auth
web/assets/requirements.txt
前章からの変化点は次の通り.
・Python から PostgreSQL を操作するために psycopg2 と psycopg2-binary の 2パッケージをインストールする
--- web/assets/requirements.txt.ORIG
+++ web/assets/requirements.txt
@@ -2,3 +2,5 @@
django-extensions==2.2.9
django-filter==2.2.0
djangorestframework==3.11.0
+psycopg2==2.8.5
+psycopg2-binary==2.8.5
web/assets/settings.py
前章からの変化点は以下である.
なお、前章では Django が生成するデフォルトの settings.py を使用していた.
・PostgreSQL の記述を追加した.
・PostgreSQL の管理者アカウントとパスワードはともに「admin
」としている.
・使用する Database 名は「django307
」としている.
--- ./web/assets/settings.py.ORIG
+++ ./web/assets/settings.py
@@ -75,8 +75,12 @@
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': 'django307',
+ 'USER': 'admin',
+ 'PASSWORD': 'admin',
+ 'HOST': 'db',
+ 'PORT': 5432,
}
}
セットアップ方法
次の通りコマンドを実行する.
$ ./setupapp.sh
セットアップ後
ファイル構成
.
|-- db
| |-- Dockerfile
| |-- data [error opening dir]
| `-- init
|-- docker-compose.yml
|-- setupapp.sh
`-- web
|-- Dockerfile
|-- app
| |-- config
| | |-- __init__.py
| | |-- asgi.py
| | |-- settings.py
| | |-- urls.py
| | `-- wsgi.py
| |-- entrypoint.sh
| `-- manage.py
`-- assets
|-- entrypoint.sh
|-- requirements.txt
`-- settings.py
動作確認方法
次の点を確認すれば良い.
✔ Dockerコンテナが次のように起動していること
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------
mydjango307 /usr/src/app/entrypoint.sh ... Up 0.0.0.0:8000->8000/tcp
✔ http://localhost:8000 にアクセスして次の画面が表示されること.
✔ http://localhost:8000/admin にアクセスして、アカウント「admin
」、パスワード「admin
」でログインできること.
✔ ./web/app/db.sqlite3 が存在していないこと
もしも存在している場合は、settings.py が正しく配置できていない疑いがある.
✔ PostgreSQL コンテナにて Database にログインできること
次のパラメータで PostgreSQL のデータベース「django307
」にログインする
項目 | 値 |
---|---|
アカウント | admin |
パスワード | admin |
ポート | 5432番 |
データベース | django307 |
$ docker-compose exec db bash -c 'PGPASSWORD=admin psql -U admin -h db -p 5432 -w django307'
そして、次のように「データベース」一覧が表示されれば良い
django307-# \l
データベース一覧
名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権限
-----------+--------+------------------+------------+-------------------+-----------------
django307 | admin | UTF8 | ja_JP.utf8 | ja_JP.utf8 |
postgres | admin | UTF8 | ja_JP.utf8 | ja_JP.utf8 |
template0 | admin | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/admin +
| | | | | admin=CTc/admin
template1 | admin | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/admin +
| | | | | admin=CTc/admin
(4 行)
以上.