Django REST Frameworkで作ったAPIをECSで動かす
はじめに
前回はDjangoで作ったAPIをdocker-composeで動かしました。
今回はそれをECSにのせて動かしたので、メモを残します
構成図
できること
このようにECSでAPIを動作させることができる
ディレクトリ構成
前回の構成と同じです。
.
├── Dockerfile
├── docker-compose.yaml
├── entrypoint.sh
├── manage.py # プロジェクト作成時に自動生成
├── requirements.txt
├── todo # プロジェクト
└── todoapp # アプリケーション
ポイント
AWSリソース作成
ECSと連携するものを予め作成しておきます。
RDS(PostgreSQL)の情報はパラメータストアに格納してタスク定義から利用するため、控えておきます。
awscliでパラメータストアに登録するコマンドはこちら
aws ssm put-parameter \
--name "<パラメータ名>" \
--type "String" \
--value "<パラメータの値>"
aws ssm put-parameter \
--name "<パラメータ名>" \
--type "SecureString" \
--value "<パラメータの値>"
./todo/settings.py
の編集
DjangoタスクがRDSを探せるように、settings.pyのデータベース箇所を編集します。
タスク定義で設定する環境変数からDBの情報を取り入れるようにします。
import os
// 略
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.getenv('DATABASE', 'postgres'),
'USER': os.getenv('DB_USER', 'postgres'),
'PASSWORD': os.getenv('DB_PASSWORD', 'postgres'),
'HOST': os.getenv('DB_HOST', 'localhost'),
'PORT': os.getenv('DB_PORT', '5432'),
}
}
コンテナビルド
プロジェクト(todo)とアプリケーション(todoapp)はコンテナ内に取り込みます。
(docker-composeではvolumeでホストと共有していたが、ECSではコンテナイメージにすべて入れるようにするため)
ということでDockerfileはこんな感じです。
FROM python:3.11.4-bookworm
ENV PYTHONUNBUFFERED 1
WORKDIR /code
COPY . /code/
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y netcat-traditional
ENTRYPOINT ["/code/entrypoint.sh"]
プロジェクト、アプリケーションディレクトリもまとめてCOPYしました。
Dockerfile,docker-compose.yamlはコンテナが使用しないものなので不要でした。
ビルドが完了したらECRへpushします。
タスク定義作成
以下の2つのタスク定義を作成します。
- API用
- Serviceで起動するタスク
- Migration用
- 単独で起動し、マイグレーションだけ実行するタスク
任意のタイミングでマイグレーションを行うため、別のタスク定義を作成しました。
使用するコンテナイメージは同じです。
タスク定義作成(パラメータ取得)
予め設定していたDB情報が保存してあるパラメータを環境変数で使用します。
コンソールから設定する場合はパラメータストアの指定を間違えないようにしましょう
マイグレーション
マイグレーション用のタスク定義からタスクを立ち上げます。
awscliから立ち上げる場合はこちら。
タスクが終了したらログからマイグレーションが正常に実行されていることを確認します。
ECSサービス起動、動作確認
マイグレーションが済んだらサービスも立ち上げます。
タスクが立ち上がったらそのIPアドレスにリクエストを投げて、そのログを確認します。
問題なさそうです!
CRUDすべてOK
おわりに
マイグレーションをタスクで実行するのはメジャーなやり方なのだろうか...
まあ動いたからヨシ
次はTerraform化ですね
参考
Discussion