2022年6月21日火曜日

DockerでDjango+PostgreSQL環境を作成する

Docker ComposeでDjango+PostgreSQLの環境を作成したので、その手順をまとめておく。Djangoのバージョンは3.2。


環境


Docker Desktop(Windows10 Pro)。
PS > docker --version
Docker version 20.10.16, build aa7e414
PS > docker-compose --version
docker-compose version 1.29.2, build 5becea4c


ファイルの準備

Dockerコンテナ作成に必要なファイルを準備する。準備するのは以下5つのファイル。


Dockerfile_web

Django用のDockerイメージを作成するDockerfile。Python公式イメージを使用。

FROM python:3.10

# 標準出力、標準エラーストリームのバッファリングを行わない
# Djangoのログをリアルタイムで出力するようにする
ENV PYTHONUNBUFFERED 1 

# ロケール設定の準備
RUN apt update \
 && apt -y install --no-install-recommends \
    locales \
 && sed -i -e 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen \
 && locale-gen

# タイムゾーン、ロケール設定
ENV TZ="Asia/Tokyo" \
    LANG="ja_JP.UTF-8"

RUN mkdir /app
WORKDIR /app

ADD requirements.txt /app/
RUN pip install -r requirements.txt


requirements.txt

DockerイメージにインストールするPythonライブラリ。DjangoとPostgreSQL接続用のDBアダプタをインストール。

Django>=3.2,<4.0
psycopg2


Dockerfile_db

PostgreSQL用のDockerイメージを作成するDockerfile。PostgreSQL公式イメージを使用。

FROM postgres:14.3

# ロケール設定に必要
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8

# タイムゾーン、ロケール設定
ENV TZ="Asia/Tokyo" \
    LANG="ja_JP.UTF-8"


docker-compose.yml

Composeファイル。PostgreSQLのデータベース領域は、後で作成するボリュームを指定する。

version: '3'

services:
  db:
    build:
     context: .
     dockerfile: Dockerfile_db
    ports: 
        - "5432"
    environment:
      POSTGRES_DB:
      POSTGRES_USER:
      POSTGRES_PASSWORD:
    volumes:
      - postgres_db:/var/lib/postgresql/data
  web:
    build:
     context: .
     dockerfile: Dockerfile_web
    command: python3 /app/manage.py runserver 0.0.0.0:8000
    volumes:
      - .\app:/app
    ports:
      - "8000:8000"
    depends_on:
      - db

volumes:
  postgres_db:
    external: true


.env

環境変数ファイル。

# プロジェクト名
COMPOSE_PROJECT_NAME=django

# PostgreSQLの設定
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres


Djangoプロジェクトの作成

ファイルの準備ができたら、まずはDjangoプロジェクト作成してmanage.pyを作成する。ここではsampleというプロジェクトを作成。

PS> docker-compose run web django-admin.py startproject sample .

このコマンドを実行すると、ホストにappフォルダが作成され、その配下にsampleフォルダとmanage.pyが作成される。

続いて、Djangoのデータベース接続設定を変更しておく。必要なら言語とタイムゾーン設定も変えておく。

...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}
...
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'


コンテナの起動

コンテナを起動する前に、PostgreSQL用のボリュームを作成する。Windowsホストのフォルダをマウントする方法もあるが、PostgreSQLコンテナでWindowsホストの領域をマウントすると以下エラーになる(Mounting data volume for Postgres in docker for Windows doesn't work)。

data directory "/var/lib/postgresql/data" has invalid permissions

そこで、Dockerでボリュームを作成して、そのボリュームをPostgreSQLのデータベース領域とする。

PS> docker volume create --name postgres_db
postgres_db

次にコンテナを起動。

PS> docker-compose up -d
Creating network "django_default" with the default driver
Creating django_db_1 ... done
Creating django_web_1 ... done
PS> docker-compose ps
    Name                  Command               State            Ports
-------------------------------------------------------------------------------
django_db_1    docker-entrypoint.sh postgres    Up      0.0.0.0:59332->5432/tcp
django_web_1   python3 /app/manage.py run ...   Up      0.0.0.0:8000->8000/tcp


コンテナを確認

各コンテナを確認してみる。まずはDjangoコンテナ。以下のように日付表示がJSTで、日本語表示になっていれば、タイムゾーンとロケールの設定が反映されている。

PS> docker-compose exec web date
2022年  6月 18日 土曜日 20:53:19 JST

次にPostgreSQLコンテナ。webコンテナと同様にタイムゾーンとロケールを確認。

PS> docker-compose exec db date
2022年  6月 18日 土曜日 20:53:19 JST 

続いてDjangoの確認。Djangoが起動していれば、ホストのブラウザでhttp://localhost:8000にアクセスすると以下の画面が表示される。

PostgreSQlへの接続確認もする。以下コマンドで接続できればOK。

PS> docker-compose exec db psql -U postgres 

最後に、Djangoのマイグレーションを実行してみる。

PS>  docker-compose run web python3 manage.py migrate
Creating django_web_run ... done
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK


0 件のコメント:

コメントを投稿