このリポジトリは、Node.js Express アプリケーションを Docker コンテナ化し、GitHub Actions を使用して Amazon ECS に自動デプロイするためのサンプルプロジェクトです。
- AWS アカウント
- GitHub アカウント
- AWS CLI のインストール(ローカル開発用、オプション)
セットアップスクリプトを使用すると、AWS リソースを自動的に作成できます:
# AWS CLI が設定されていることを確認
aws configure
# セットアップスクリプトを実行
./setup-aws.shこのスクリプトは以下のリソースを自動的に作成します:
- ECR リポジトリ
- ECS クラスター
- CloudWatch ロググループ
- セキュリティグループ
- ECS タスク定義
- ECS サービス
以下の手順で手動で AWS リソースを作成することもできます:
以下の AWS リソースを作成する必要があります:
aws ecr create-repository \
--repository-name typescript-container \
--region ap-northeast-1aws ecs create-cluster \
--cluster-name typescript-container-cluster \
--region ap-northeast-1aws logs create-log-group \
--log-group-name /ecs/typescript-container \
--region ap-northeast-1ecsTaskExecutionRole と ecsTaskRole が必要です。これらのロールが存在しない場合は、AWS コンソールまたは CLI で作成してください。
- ecsTaskExecutionRole: ECR からイメージをプル、CloudWatch Logs にログを書き込むための権限
- ecsTaskRole: タスクが実行時に必要とする AWS サービスへのアクセス権限
.aws/task-definition.json ファイルを開き、以下の値を実際の値に置き換えてください:
YOUR_AWS_ACCOUNT_ID→ あなたの AWS アカウント ID(例: 123456789012)
まず、VPC とサブネット、セキュリティグループを確認してから、ECS サービスを作成します:
# VPC IDとサブネットIDを確認
aws ec2 describe-vpcs --region ap-northeast-1
aws ec2 describe-subnets --region ap-northeast-1
# セキュリティグループの作成(ポート3000を許可)
aws ec2 create-security-group \
--group-name typescript-container-sg \
--description "Security group for typescript container" \
--vpc-id vpc-xxxxx \
--region ap-northeast-1
# インバウンドルールの追加
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxx \
--protocol tcp \
--port 3000 \
--cidr 0.0.0.0/0 \
--region ap-northeast-1最初のデプロイの前に、タスク定義を手動で登録する必要があります:
aws ecs register-task-definition \
--cli-input-json file://.aws/task-definition.json \
--region ap-northeast-1その後、ECS サービスを作成します:
aws ecs create-service \
--cluster typescript-container-cluster \
--service-name typescript-container-service \
--task-definition typescript-container-task \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxx],securityGroups=[sg-xxxxx],assignPublicIp=ENABLED}" \
--region ap-northeast-1リポジトリの Settings > Secrets and variables > Actions から以下のシークレットを追加してください:
| シークレット名 | 説明 | 取得方法 |
|---|---|---|
AWS_ACCESS_KEY_ID |
AWS アクセスキー ID | IAM ユーザーから取得 |
AWS_SECRET_ACCESS_KEY |
AWS シークレットアクセスキー | IAM ユーザーから取得 |
IAM ユーザーに必要な最小限の権限:
テスト環境では以下の管理ポリシーを使用できます:
- AmazonEC2ContainerRegistryPowerUser
- AmazonECS_FullAccess
- CloudWatchLogsFullAccess
本番環境では最小権限の原則に従ってカスタム IAM ポリシーを作成することを強く推奨します:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"ecs:RegisterTaskDefinition"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "arn:aws:iam::*:role/ecsTaskExecutionRole"
}
]
}.github/workflows/deploy-to-ecs.yml ファイルの環境変数を確認し、必要に応じて変更してください:
env:
AWS_REGION: ap-northeast-1 # リージョン
ECR_REPOSITORY: typescript-container # ECR リポジトリ名
ECS_SERVICE: typescript-container-service # ECS サービス名
ECS_CLUSTER: typescript-container-cluster # ECS クラスター名main または master ブランチにプッシュすると、自動的に GitHub Actions が実行され、ECS にデプロイされます。
git add .
git commit -m "Update application"
git push origin mainGitHub リポジトリの Actions タブから「Deploy to Amazon ECS」ワークフローを選択し、「Run workflow」ボタンをクリックして手動で実行することもできます。
- GitHub Actions のログを確認
- AWS ECS コンソールでタスクの状態を確認
- CloudWatch Logs でアプリケーションログを確認
- タスクのパブリック IP アドレスにアクセスして動作確認
タスクの IP アドレスを取得:
aws ecs list-tasks \
--cluster typescript-container-cluster \
--service-name typescript-container-service \
--region ap-northeast-1
aws ecs describe-tasks \
--cluster typescript-container-cluster \
--tasks <task-arn> \
--region ap-northeast-1docker-compose up --buildブラウザで http://localhost:3000 にアクセス
npm install
npm start.
├── .aws/
│ └── task-definition.json # ECS タスク定義
├── .github/
│ └── workflows/
│ └── deploy-to-ecs.yml # GitHub Actions ワークフロー
├── Dockerfile # Docker イメージ定義
├── docker-compose.yml # ローカル開発用
├── app.js # Express アプリケーション
├── package.json # Node.js 依存関係
└── README.md # このファイル
タスク定義(.aws/task-definition.json)で CPU とメモリを調整できます:
cpu: "256", "512", "1024", "2048", "4096"memory: CPU に応じた値(詳細は AWS ドキュメント参照)
タスク定義の environment セクションに環境変数を追加できます:
"environment": [
{
"name": "PORT",
"value": "3000"
},
{
"name": "NODE_ENV",
"value": "production"
}
]- AWS アクセスキーは GitHub Secrets として安全に保管
- 本番環境では最小権限の原則に従った IAM ポリシーを使用(上記の例を参照)
- セキュリティグループで必要最小限のポートのみ開放
- 本番環境では:Application Load Balancer (ALB) を使用し、ECS タスクをプライベートサブネットに配置することを強く推奨
- 定期的なセキュリティパッチの適用とイメージの更新
- シークレット情報は AWS Secrets Manager または Systems Manager Parameter Store を使用
MIT