0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPI構成メモ:4つのコンテナ(cws-instrumentation-init, datadog-agent, migration-runner, my-app)による本番設計

Posted at

はじめに

AWS ECS Fargate 上で FastAPI アプリを運用するためのタスク定義を作成した際の構成を整理しました。

Datadog のログ監視、初期化処理、マイグレーション実行などを複数のコンテナで分担する構成としています。

個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。

書こうと思ったきっかけ

受講しているITスクールのハッカソンの開発の一環で、Datadogやマイグレーションの構成に悩んだため、今後の再利用と共有のために記事としてまとめておくことにしました。

作成後の画面

Screenshot 2025-05-11 at 8.24.17.png

作成したタスク定義JSON

{
  "containerDefinitions": [
    {
      "name": "cws-instrumentation-init",
      "image": "datadog/cws-instrumentation:latest",
      "cpu": 0,
      "portMappings": [],
      "essential": false,
      "command": [
        "/cws-instrumentation",
        "setup",
        "--cws-volume-mount",
        "/cws-instrumentation-volume"
      ],
      "environment": [],
      "mountPoints": [
        {
          "sourceVolume": "cws-instrumentation-volume",
          "containerPath": "/cws-instrumentation-volume",
          "readOnly": false
        }
      ],
      "volumesFrom": [],
      "user": "0",
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/datadog",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "cws-instrumentation-init"
        }
      },
      "systemControls": []
    },
    {
      "name": "datadog-agent",
      "image": "datadog/agent:latest",
      "cpu": 0,
      "portMappings": [],
      "essential": true,
      "environment": [
        {
          "name": "DD_CONTAINER_METRICS_ENABLED",
          "value": "true"
        },
        {
          "name": "DD_RUNTIME_SECURITY_CONFIG_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_TRACE_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_ORCHESTRATOR_EXPLORER_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_SYSTEM_PROBE_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_APM_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_LOGS_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_API_KEY",
          "value": "xxx"
        },
        {
          "name": "DD_SECURITY_AGENT_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_SITE",
          "value": "ap1.datadoghq.com"
        },
        {
          "name": "DD_PROCESS_AGENT_ENABLED",
          "value": "false"
        },
        {
          "name": "ECS_FARGATE",
          "value": "true"
        },
        {
          "name": "DD_PROCESS_CONFIG_ENABLED",
          "value": "false"
        },
        {
          "name": "DD_RUNTIME_SECURITY_CONFIG_EBPFLESS_ENABLED",
          "value": "false"
        }
      ],
      "mountPoints": [],
      "volumesFrom": [],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/datadog",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "datadog-agent"
        }
      },
      "healthCheck": {
        "command": [
          "CMD-SHELL",
          "/probe.sh"
        ],
        "interval": 30,
        "timeout": 5,
        "retries": 2,
        "startPeriod": 60
      },
      "systemControls": []
    },
    {
      "name": "my-app-repo",
      "image": "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo:latest",
      "cpu": 0,
      "portMappings": [
        {
          "containerPort": 8000,
          "hostPort": 8000,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "entryPoint": [
        "/bin/sh",
        "-c"
      ],
      "command": [
        "uvicorn main:app --host 0.0.0.0 --port 8000 --log-level info"
      ],
      "environment": [],
      "mountPoints": [
        {
          "sourceVolume": "cws-instrumentation-volume",
          "containerPath": "/cws-instrumentation-volume",
          "readOnly": true
        }
      ],
      "volumesFrom": [],
      "linuxParameters": {
        "capabilities": {
          "add": [
            "SYS_PTRACE"
          ],
          "drop": []
        }
      },
      "dependsOn": [
        {
          "containerName": "datadog-agent",
          "condition": "HEALTHY"
        },
        {
          "containerName": "cws-instrumentation-init",
          "condition": "SUCCESS"
        },
        {
          "containerName": "migration-runner",
          "condition": "SUCCESS"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/datadog",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "my-app-repo"
        }
      },
      "systemControls": []
    },
    {
      "name": "migration-runner",
      "image": "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo:latest",
      "essential": false,
      "entryPoint": [
        "/bin/sh",
        "-c"
      ],
      "command": [
        "cd /app && alembic upgrade head"
      ],
      "environment": [
        {
          "name": "AWS_REGION",
          "value": "ap-northeast-1"
        },
        {
          "name": "MYSQL_PW",
          "value": "xxx"
        },
        {
          "name": "MYSQL_USER",
          "value": "myuser"
        },
        {
          "name": "MYSQL_HOST",
          "value": "xxx.ap-northeast-1.rds.amazonaws.com"
        },
        {
          "name": "MYSQL_DB",
          "value": "mydatabase"
        }
      ],
      "dependsOn": [
        {
          "containerName": "datadog-agent",
          "condition": "HEALTHY"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/datadog",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "migration-runner"
        }
      }
    }
  ],
  "family": "Datadog",
  "taskRoleArn": "arn:aws:iam::xxx:role/ecs-task-execution-role",
  "executionRoleArn": "arn:aws:iam::xxx:role/ecs-task-execution-role",
  "networkMode": "awsvpc",
  "volumes": [
    {
      "name": "cws-instrumentation-volume",
      "host": {}
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "256",
  "memory": "512"
}

コンテナ構成

  • cws-instrumentation-init: DatadogのCWS(Cloud Workload Security)初期化用コンテナ。セットアップスクリプトを実行して終了します。
  • datadog-agent: Datadogエージェント本体。ログ収集やメトリクス監視を担当し、すべてのコンテナの起動に先立って健康状態チェックを提供します。
  • migration-runner: Alembic を使ってマイグレーションを実行する補助的なコンテナ。alembic upgrade head を実行後に終了します。
  • my-app-repo: 本番アプリケーション(FastAPI)。依存関係がすべて整った後に uvicorn によって起動されます。

特徴的な設定ポイント

  • my-app-repomigration-runner は同一イメージを使用しますが、起動時の command によって動作が異なります。
  • migration-runneressential: false に設定し、アプリ本体とは独立して動作します。
  • すべてのログは Datadog のロググループ /ecs/datadog に送信され、awslogs-stream-prefix によって分類されます。
  • dependsOn を活用し、アプリの起動順序を制御しています。

まとめ

このように、Fargate 上で複数コンテナを使い分けることで、初期化処理・マイグレーション・監視・アプリ本体の機能を疎結合に保ちながら、安全にアプリを起動できます。

特に Alembic のマイグレーションを ECS タスク起動時に組み込むことで、デプロイ前後の整合性も確保できると思っています...!

今後は CI/CD パイプラインと連携し、この構成をより自動化していく予定です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?