😍

AWSCopiltが便利だった

に公開

docker-composeからECSへの移行

前提として

  • アプリ作成は、基本docker-composeを使用している

以前は以下のようなプロジェクトのAWSECSへの移行は結構手間だった

  1. ECS CLIのインストール
  2. ECS CLIの設定
  3. docker-composeファイルからECSリソースを作成
  4. Docker ECSコンテキストの作成
  5. ECSコンテキストに切り替え
  6. 構成のデプロイ
  7. その他、追加設定オプションの設定など

このように結構大変で難しかったです。結果、直接ECRにイメージをプッシュして、タスク定義をJsonで書いてしまって運用の方が良い気がしてました。

AWSCopiltを使用すると簡単にECSにデプロイしてくれました

copilot initコマンドが全部設定してくれるものです。
ただし、AWS上のサービスをすべて1から作成していく形でカオスなのでおすすめしません。。。セキュリティ的にももしも自分の認識していないサービスが立ち上がっていたりすると管理が難しいです。

  • ECSへのデプロイなので、docker-compose.ymlとバックエンド、フロントエンドのDockerfileがあり、アプリが動いていれば簡単に移行できました。特にdocker-compose.ymlの内容はAWS ECSを作成する上で使用することはありません。

  • 内容は参考まで以下、簡単な形です

docker-compose.yml
version: '3.8'

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app  # 開発モードではこのボリュームマウントを有効化
      - /app/node_modules
    environment:
      - NUXT_PUBLIC_API_BASE_URL=http://backend:8000
      - HOST=0.0.0.0
      - NODE_ENV=development  # 開発モードに変更
    depends_on:
      - backend
    networks:
      - app-network
    restart: unless-stopped  # 開発環境では手動制御できるようにする

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/app
      # 開発環境でもデータをホスト間で共有できるようにする
      - backend_data:/app/data
    environment:
      - DEBUG=1  # 開発モードを有効化
      - ALLOWED_HOSTS=localhost,127.0.0.1,backend,frontend  # コンテナ名を追加
    command: python manage.py runserver 0.0.0.0:8000  # 開発環境ではrunserverを使用
    networks:
      - app-network
    restart: unless-stopped  # 開発環境では手動制御できるようにunless-stoppedを維持

networks:
  app-network:
    driver: bridge

# データ共有用ボリューム(開発環境でも必要)
volumes:
  backend_data:
Dockerfile(frontend)
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

# Amazon Linux 2環境での実行のために環境変数を設定
ENV HOST 0.0.0.0
ENV PORT 3000

# ビルドステップを追加
RUN npm run build

EXPOSE 3000

# 開発モードで実行するように変更
CMD ["npm", "run", "dev"]
Dokcerfile(backend)
FROM python:3.9-slim

WORKDIR /app

# 依存関係のインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのコピー
COPY . .

# マイグレーションの実行
RUN python manage.py migrate

# 起動コマンド(Django開発サーバーを使用)
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8000/api/ || exit 1

AWSCopilotを使用して構築を行ってみます。今回VPC周りは既存のものを使用していきます。その中でECSのfargateが起動する形です。

  1. まずアプリケーションを初期化(アプリの名前を決めます)
copilot app init menta-app
  1. その後、再度環境(env)を作成. aws configure --profile xxx は行っておいて下さい。vpc、subnetは既存を指定です
copilot env init \
  --name prod \
  --profile test \
  --region ap-northeast-1 \
  --import-vpc-id vpc-xxx \
  --import-public-subnets subnet-xxx,subnet-xxx
  1. サービス(今回はALB付きWebサービス)の作成、バックエンドも同様に作成
フロントエンドサービスの作成
copilot svc init \
  --name frontend \
  --svc-type "Load Balanced Web Service" \
  --dockerfile ./frontend/Dockerfile \
  --port 3000
バックエンドサービスの作成
copilot svc init \
  --name backend \
  --svc-type "Backend Service" \
  --dockerfile ./backend/Dockerfile \
  --port 8000
  1. サービス(ECS)のデプロイ
copilot svc deploy --name frontend --env prod

もしも、上記4でエラーの場合は以下

copilot env deploy --name prod
  1. サービスのデプロイ
    prod環境のデプロイが完了したら、
    再度サービスのデプロイコマンドを実行してください。これで4で用意したものが動きだします。
copilot svc deploy --name frontend --env prod

または、

copilot svc deploy --name backend --env prod
  1. サービスの削除
copilot svc delete --name frontend --env prod

まとめ

AWS Copilotは、コンテナ化されたアプリケーションをAWS上にデプロイするためのコマンドラインインターフェース(CLI)ツールです。特に、既存のdocker-compose.ymlDockerfileといったDocker構成ファイルを利用して、少ないコマンドでAWSの各種サービスを簡単に構築・管理できる点が大きな特徴でした。快適に利用できそう!!!
既にDockerfiledocker-compose.ymlで開発を進めているプロジェクトであれば、スムーズにAWSへの移行が可能です。

補足

AWS Copilotの主な機能とDocker構成の活用

AWS Copilotは、開発者がインフラの複雑さを意識することなく、アプリケーションのコードに集中できるよう設計されています。主な機能とDocker構成の活用方法は以下の通りです。

  1. アプリケーションと環境の初期化:

    • copilot init: このコマンドを実行すると、AWS Copilotは現在のディレクトリにあるDockerfiledocker-compose.ymlを検出し、それに基づいてAWS上でアプリケーションを動作させるための設定(マニフェストファイル manifest.yml)を生成します。
    • 既存のDocker構成がない場合でも、対話形式でアプリケーションの種類(例: "Load Balanced Web Service" や "Backend Service")を選択することで、基本的なDockerfileやマニフェストファイルの雛形を作成してくれます。
  2. サービスのデプロイ:

    • copilot svc deploy: Dockerfileからコンテナイメージをビルドし、Amazon ECR (Elastic Container Registry) にプッシュします。その後、マニフェストファイルの設定に基づいて、Amazon ECS (Elastic Container Service) や AWS Fargate を使用してサービスをデプロイします。
    • docker-compose.yml を利用している場合、Copilot はその定義を解釈し、複数のコンテナで構成されるアプリケーションをデプロイすることも可能です(ただし、全てのdocker-composeの機能が直接的にサポートされるわけではなく、CopilotのマニフェストファイルでAWSネイティブのサービスに置き換えて設定することが推奨されます)。
  3. 環境の構築:

    • copilot env init: 開発(dev)、ステージング(staging)、本番(prod)といった環境を簡単に作成できます。これにより、環境ごとに異なる設定やリソースを管理できます。
    • 各環境には、VPC、サブネット、ロードバランサーなどのネットワークインフラストラクチャが含まれます。
  4. パイプラインの構築:

    • copilot pipeline init および copilot pipeline deploy: AWS CodePipelineを利用したCI/CDパイプラインを簡単に構築できます。これにより、コードの変更をリポジトリにプッシュするだけで、自動的にビルド、テスト、デプロイが行われるようになります。
  5. アドオンによる追加リソースの作成:

    • copilot storage init: Amazon S3バケットやAmazon DynamoDBテーブルといったストレージリソースをサービスに簡単に追加できます。
    • CopilotはCloudFormationを内部的に使用しており、これらのアドオンもCloudFormationテンプレートとして定義・管理されます。

主なコマンドと役割

  • copilot init: 新しいアプリケーションとサービス、または環境を初期化します。Dockerfiledocker-compose.ymlを検出して設定を生成します。
  • copilot app init: アプリケーションの初期設定を行います。
  • copilot env init: 新しいデプロイ環境(例: test, prod)を作成します。VPCやクラスターなどがプロビジョニングされます。
  • copilot svc init: 新しいサービスをアプリケーションに追加します。デプロイするコンテナイメージやポート設定などを定義します。
  • copilot svc deploy: サービスをビルドし、指定された環境にデプロイします。
  • copilot svc logs: デプロイされたサービスのログを表示します。
  • copilot svc status: サービスのステータスやエンドポイントURLなどを確認します。
  • copilot pipeline init: CI/CDパイプラインを初期化します。
  • copilot pipeline deploy: CI/CDパイプラインをデプロイまたは更新します。
  • copilot storage init: S3バケットやDynamoDBテーブルなどのストレージリソースを定義します。

AWS Copilotによって作成・利用される主なAWSサービス

AWS Copilotは、以下のようなAWSサービスを内部的に利用・作成し、連携させます。

  • コンテナ関連:
    • Amazon ECS (Elastic Container Service): コンテナオーケストレーションサービス。
    • AWS Fargate: サーバーレスのコンテナ実行環境。
    • Amazon ECR (Elastic Container Registry): Dockerコンテナイメージの保存・管理。
  • ネットワーク関連:
    • Amazon VPC (Virtual Private Cloud): 論理的に分離された仮想ネットワーク。
    • Application Load Balancer (ALB) / Network Load Balancer (NLB): トラフィックの分散。
    • Amazon Route 53: DNSサービス(カスタムドメイン利用時)。
    • AWS App Mesh: サービスメッシュ(オプション)。
  • CI/CD:
    • AWS CodePipeline: CI/CDパイプラインの構築・自動化。
    • AWS CodeBuild: ソースコードのコンパイル、テスト、パッケージ化。
    • AWS CodeCommit または GitHub/Bitbucket: ソースコードリポジトリ。
  • モニタリング・ロギング:
    • Amazon CloudWatch: ログ収集、メトリクス監視、アラーム設定。
  • インフラストラクチャ・アズ・コード:
    • AWS CloudFormation: インフラ構成の自動化と管理。Copilotの操作の多くはCloudFormationスタックとしてデプロイされます。
  • ストレージ(アドオン経由):
    • Amazon S3 (Simple Storage Service): オブジェクトストレージ。
    • Amazon DynamoDB: NoSQLデータベースサービス。
    • Amazon Aurora Serverless: リレーショナルデータベースサービス(アドオンで対応)。
  • その他:
    • AWS IAM (Identity and Access Management): 権限管理。
    • AWS Systems Manager Parameter Store: 設定値や機密情報の保存。

Discussion