nikkie-ftnextの日記

イベントレポートや読書メモを発信

Djangoの開発でWebアプリとDB(postgreSQL)の両方をdocker compose upで動かしたときに、アプリは自動でmigrateしてからrunserverした状態にしたい

簡略版でお送りします。
もっといいやり方をご存じの方はぜひ教えてください!

目次

宿題:自動でmigrateしてからrunserverした状態にしたい

docker compose upDjangoアプリケーションとDB(postgreSQL)の両方が立ち上がる環境を構築中のnikkie氏。

出発点となる環境は用意できていて

残った宿題にアプローチしています。

今回アプローチする宿題はこちら!

docker compose run webpython manage.py migrateを都度叩く必要があります

docker-compose.ymlの中でDockerイメージにrunserverコマンドを渡しています

services:
  web:
    command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]

これにより、docker compose upした後で、別のシェルでdocker compose run web python manage.py migrateと叩く必要がありました。

docker compose upするだけで必要なmigrationが行われ、runserverまでされたらとても便利ですよね?
その方法を調べました。

migrateからrunserverまでをまとめたentrypoint.shを作る!

まとめたentrypoint.shを作って対処しました!

参考にしたのはこちら

collectstatic・migrate・runserverをまとめています。

migrateは必要がないときには何もしないのがポイント高いです。
entrypoint.shでコマンドを順番に呼ぶだけで、必要なmigrationが行われ、runserverまでされた状態が実現できます!

entrypoint.sh

#!/usr/bin/env bash
set -euo pipefail

echo "Apply database migrations"
python manage.py migrate
echo

echo "Start server"
python manage.py runserver 0.0.0.0:8000

Dockerfile(差分)

FROM python:3.11-bookworm as builder
WORKDIR /code
COPY requirements.lock /code/
RUN pip install --no-cache-dir -r requirements.lock

FROM python:3.11-bookworm
WORKDIR /code
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY bad_sql_injection /code/
+COPY entrypoint.sh /code/
+CMD [ "./entrypoint.sh" ]
  • entrypoint.shはmanage.pyと同階層に置かれます
  • docker compose runで上書きできるよう、CMD命令としました

docker-compose.yml(差分)

version: '3.9'

services:
  db:
    image: postgres:15.3
    environment:
      - POSTGRES_DB=badapp
      - POSTGRES_USER=developer
      - POSTGRES_PASSWORD=mysecretpassword
    volumes:
      - ./data/db:/var/lib/postgresql/data
    ports:
      - "5432:5432"
  web:
    build:
      context: .
      dockerfile: Dockerfile
-    command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
    ports:
      - "8000:8000"
    depends_on:
      - db
  • DockerfileでCMD命令を指定したので、commandは削除しました

残っている宿題

postgreSQLが参照するフォルダ(docker-compose.ymlのvolumes)を消してから立ち上げると、うまくいったりいかなかったりします(ガチャだ!!)

docker compose downとdocker compose upを繰り返すという方法で立ち上げることはできます(もっときれいに解決したい!)