💡

Django REST Frameworkで作ったAPIをECSで動かす

2023/07/10に公開

はじめに

前回は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の情報を取り入れるようにします。

settings.py
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します。
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html

タスク定義作成

以下の2つのタスク定義を作成します。

  • API用
    • Serviceで起動するタスク
  • Migration用
    • 単独で起動し、マイグレーションだけ実行するタスク

任意のタイミングでマイグレーションを行うため、別のタスク定義を作成しました。
使用するコンテナイメージは同じです。

https://repost.aws/questions/QUGsow-U-jSUyNcTcHOCst6g/rds-db-migrations-using-ecs-and-fargate

タスク定義作成(パラメータ取得)

予め設定していたDB情報が保存してあるパラメータを環境変数で使用します。
コンソールから設定する場合はパラメータストアの指定を間違えないようにしましょう

マイグレーション

マイグレーション用のタスク定義からタスクを立ち上げます。
awscliから立ち上げる場合はこちら。
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecs/run-task.html

タスクが終了したらログからマイグレーションが正常に実行されていることを確認します。

ECSサービス起動、動作確認

マイグレーションが済んだらサービスも立ち上げます。
タスクが立ち上がったらそのIPアドレスにリクエストを投げて、そのログを確認します。

問題なさそうです!
CRUDすべてOK

おわりに

マイグレーションをタスクで実行するのはメジャーなやり方なのだろうか...
まあ動いたからヨシ

次はTerraform化ですね

参考

https://docs.djangoproject.com/en/4.2/ref/settings/#databases
https://jprechac.medium.com/running-django-migrations-with-ecs-76c856afdd0a

Discussion