0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS における Docker コンテナ起動の全体像(ECR / ECS / Terraform)

Last updated at Posted at 2025-12-20

Terraform で AWS のコンテナ環境(ECS / ECR)を構築すると、どのリソースが・どのタイミングで・何をしているのかが分かりづらくなりがちです。私自身、ECSの仕組みを理解するのにとても時間がかかりました。

本ドキュメントでは、AWS 上で Docker コンテナが起動するまでの流れを、コードを見ながら「役割ベース」で理解することを目的とします。
※ 手順書ではなく、全体構造を掴むためのものですので、そのことを前提に読んでいただけると嬉しいです。

用語の前提整理

用語 役割
ECR Docker イメージを保管するレジストリ
ECS Docker コンテナを起動・管理するサービス
Task Definition 「このイメージを、どんな設定で起動するか」を定義する設計書
Service Task Definition を使って、タスクを起動・維持する仕組み

※ IAM / VPC / ALB の詳細な構築方法は本ドキュメントでは扱いません
(ECS がそれらを“使って何をするか”に焦点を当てます)

全体像

AWS のコンテナ運用は、大きく次の 2 フェーズに分かれます。

  • Docker イメージを作って ECR に置く
  • ECS がそのイメージを使ってコンテナを起動する
① Dockerfile作成
② Dockerイメージをビルド
③ ECRリポジトリへイメージをpush
④ ECSタスク定義で ECR のイメージURIを指定する
⑤ ECSクラスター上で サービス or RunTask を実行する
⑥ ECSがタスク定義を参照し、ECRからイメージを pull する
⑦ コンテナが起動し、アプリケーションが起動する

👉 ECS は Dockerfile も build 処理もしません。
👉 ECS が知り得るのは「ECR にあるイメージ」だけになります。

以下の図を参考にしてください。
スクリーンショット 2025-12-20 15.34.06.png
参照:https://medium.com/%40ahmedSalem2020/deploying-a-docker-nginx-image-using-amazon-ecr-and-ecs-119e7d9b78d9

1. Dockerfile作成

まずはコンテナのベースとなるDockerfileを作成します。
Dockerfileでは以下を定義します。

  • どの OS / ランタイムを使うか
  • アプリケーションの配置場所
  • コンテナ起動時に何を実行するか
# docker/env.prod/node/Dockerfile

# コンテナのベースとなる Node.js 実行環境を指定
FROM node:22-alpine

# コンテナ内での作業ディレクトリ
WORKDIR /work/backend

# ビルド済みの Next.js アプリケーションを配置
COPY ./.next/standalone .
COPY ./.next/static ./.next/static
COPY ./public ./public

# コンテナ起動時に最初に実行されるスクリプトを配置
COPY ./docker/env.prod/node/entrypoint.sh ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

# コンテナが起動したら Node.js アプリを起動する、という定義
EXPOSE 3000
ENTRYPOINT ["./entrypoint.sh"]
CMD ["node", "server.js"]

2. Docker イメージを build & ECR に push(CI)

目的:ECS が使える形で Docker イメージを登録します。
ECS は Dockerfile を直接扱えないため、事前に Docker イメージを作成し、ECR に登録する必要があります。この処理を GitHub Actions で自動化します。

# .github/workflows/app-node.yaml
name: build-and-push

# 本番用ブランチに push されたタイミングで実行
on:
  push:
    branches: [release/prod]

jobs:
  build:
    runs-on: ubuntu-latest

    # GitHub Actions が AWS にアクセスするための認証設定
    steps:
      - uses: actions/checkout@v3

      # AWS認証(OIDC)
      - uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-region: ap-northeast-1
          role-to-assume: arn:aws:iam::<account-id>:role/ExternalGithubForDeploy

      # ECR に Docker push するためのログイン
      - uses: aws-actions/amazon-ecr-login@v1

      # Dockerfile を使ってイメージを build
      # build したイメージを ECR に push
      - uses: docker/build-push-action@v4
        with:
          context: .
          file: ./docker/env.prod/node/Dockerfile
          push: true

          # イメージを一意に識別するため、commit SHA をタグに使用
          tags: <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/<service-name>:${{ github.sha }}

👉 ECS は GitHub Actions や Docker build には一切関与しません。

3. ECR(イメージの保管場所)

目的:ECS が参照するイメージの置き場です。

<account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/<service-name>:<tag>

ECS はこの URI を指定されることで、Docker イメージを取得し、「どのバージョンを起動するか」は タグで制御されます。
👉 ECR はただの保管庫、起動はしません。

4. ECS Task Definition(起動設計書)

目的:「このイメージを、どう起動するか」を ECS に伝える
Task Definition では、以下を定義しています。

  • 使用する Docker イメージ
  • CPU / メモリ
  • ポート
  • ログ出力設定
resource "aws_ecs_task_definition" "this" {
  # タスク定義名
  family             = "<cluster-name>"
  
  # Fargate 上で確保するリソース量
  cpu                = 1024
  memory             = 2048
  
  requires_compatibilities = ["FARGATE"]
  network_mode       = "awsvpc"

  execution_role_arn = var.task_role_arn
  task_role_arn      = var.task_role_arn

  container_definitions = jsonencode([
    {
      name  = "<service-name>"
      
      # ECS が pull する Docker イメージ
      image = "<account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/<service-name>:${var.image_tag}"
      essential = true
      portMappings = [{
        containerPort = 3000
      }]
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          awslogs-group  = aws_cloudwatch_log_group.<service-name>.name
          awslogs-region = "ap-northeast-1"
        }
      }
    }
  ])
}

👉 ECS は Task Definition を見て初めて「何を起動するか」を理解します。

5. ECS Service(タスク起動のトリガー)

目的:Task Definition を使ってタスクを起動・維持します。
Service は「いつ・いくつ」タスクを起動するかを管理します。

resource "aws_ecs_service" "this" {
  name            = "<service-name>"
  cluster         = aws_ecs_cluster.default.id
  task_definition = aws_ecs_task_definition.this.arn
  desired_count   = 1
  launch_type     = "FARGATE"

  network_configuration {
    subnets         = var.vpc_subnets
    security_groups = var.vpc_security_groups
  }
}

👉 関係性

Service
  └─ Task Definition
        └─ ECR Image URI

6. タスク起動時に ECS が行うこと(超重要)

① Service / RunTask が実行される
② ECS が Task Definition を取得
③ ECS が ECR にアクセス
④ Docker イメージを pull
⑤ コンテナを起動
⑥ ENTRYPOINT / CMD を実行

👉 ここで初めて Docker コンテナが動きます。

7. コンテナ起動 → アプリケーション起動

  • Node.js / Next.js が起動
  • ALB 経由でリクエストを受信
  • CloudWatch Logs にログ出力

まとめ

  • Dockerfile:アプリを起動できる形にする
  • CI / ECR:ECS が使える形でイメージを置く
  • Task Definition:どう起動するかを ECS に伝える
  • Service:タスクを起動・維持する
  • ECS:全部を自動で実行する実行役

いかがでしたか?AWS上で動くDockerコンテナ運用のイメージはつきましたか?
本ドキュメントはあくまでDockerコンテナがAWS上で動くための全体構成をざっくり理解するためのものなので、全体のフローを理解する用として参照していただければ嬉しいです。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?