Closed9

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

not75743not75743

流れ

うまく動かせた
こんな感じか

  • AWSリソース作成
    • RDSの情報をsettings.pyに使用するので最初に作っておく
    • あとはcloudwatchとかその辺
  • コンテナビルド
    • docker-composeではvolumeでホストと共有していたが、コンテナイメージにすべて入れるようにする
    • settings.pyにDB(RDS)の情報を記載
    • ビルドしてECRへpush
  • タスク定義作成
    • サービス用とマイグレーション用に2つ用意する
    • 双方同じイメージを使用するが、後者はマイグレーションのコマンドを指定する
      • python manage.py migrate
  • マイグレーション実行
    • cloudwatchのログか、RDSにログインして確認する
  • サービス作成、動作確認
not75743not75743

AWSリソース作成

ECSクラスタ、SG、RDS等を作成する。
RDSの情報はsetting.pyに書き込むので予め控えておく

パラメータの作成はawscliだと楽

aws ssm put-parameter \
  --name "<パラメータ名>" \
  --type "String" \
  --value "<パラメータの値>"
  
aws ssm put-parameter \
  --name "<パラメータ名>" \
  --type "SecureString" \
  --value "<パラメータの値>"
not75743not75743

構成図

メインのサービス以外は省略
migration時に別タスクを使うのがポイント

not75743not75743

コンテナビルド、ECRへのpush

ディレクトリ構成(前回と同様です)

.
├── Dockerfile
├── docker-compose.yaml
├── entrypoint.sh
├── manage.py # プロジェクト作成時に自動生成
├── requirements.txt
├── todo # プロジェクト
└── todoapp # アプリケーション

./todo/settings.pyの編集

Djangoタスクがデータベースを探せるように、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でホストと共有していたが、コンテナイメージにすべて入れるようにするため)
ということで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するということですね。
docker-composeファイル等も含まれているのであまり良くない例です。

ビルドが完了したらECRへpushします

not75743not75743

タスク定義作成

migration用


コマンドの指定

            "command": [
                "python",
                "manage.py",
                "migrate"
            ],

②パラメータストアからDB情報の取り出し

            "secrets": [
                {
                    "name": "DATABASE",
                    "valueFrom": "/ecs/django-test/DATABASE"
                },
                {
                    "name": "DB_PORT",
                    "valueFrom": "/ecs/django-test/DB_PORT"
                },
                {
                    "name": "DB_USER",
                    "valueFrom": "/ecs/django-test/DB_USER"
                },
                {
                    "name": "DB_HOST",
                    "valueFrom": "/ecs/django-test/DB_HOST"
                },
                {
                    "name": "DB_PASSWORD",
                    "valueFrom": "/ecs/django-test/DB_PASSWORD"
                }
            ],

service用

実行するコマンドが異なるだけ。

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

コンソールから設定する場合はパラメータストアの指定を間違えないようにしましょう

not75743not75743

マイグレーション

マイグレーションを実行するだけなので、サービスではなくタスク単体で用意します。
タスクが停止したらログからマイグレーションが正常に実行されていることを確認します

not75743not75743

サービス展開・動作確認

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

問題なさそう

このスクラップは2023/07/10にクローズされました