役割別でコンテナを用意するとは?DockerfileからAWS ECSまで解説
Dockerでは、Web・アプリ・Workerなど、役割ごとにコンテナを分ける構成がよく使われます。
- Web
- リクエストを受け付ける
- App
- アプリケーションを実行する
- DB
- データを保存する
- Worker
- バックグラウンド処理を実行する
今回は、役割ごとにコンテナを用意してAWS ECSで動かすまでを見ていきます。
流れは次のようになります。
- 必要な役割ごとにDockerfileを用意する
- Dockerfileの中身を書く
- ローカルでDockerイメージを作る
- ローカルで起動確認する
- DockerイメージをAmazon ECRへpushする
- ECRでDockerイメージを確認する
- ECSのTask DefinitionにECRのイメージを指定する
- ECSでコンテナを起動して確認する
まず必要なDockerfileを用意する
最初に必要なコンテナを決めて、ローカルのエディタでDockerfileを用意します。
例えば、
- Web → Nginx
- App → Node.js
- Worker → バックグラウンド処理
なら、次のように配置できます。
my-project/
├── web/
│ └── Dockerfile
├── app/
│ └── Dockerfile
└── worker/
└── Dockerfile
Dockerfileの中身を書く
Dockerfileの中身は、基本的に以下を参考にして決めます。
- Dockerfileの書き方
- ベースイメージやバージョン
- 使用する言語やミドルウェア
- Node.js、Nginx、PHPなど各公式ドキュメント
- 既存プロジェクト
- すでにDockerfileがある場合は、その構成や使用しているバージョンを確認
特に新しく作る場合は、Docker Hubで使用する技術の公式イメージを探し、
そのイメージの使用例を参考にDockerfileを書いていきます。
ローカルでDockerイメージを作る
複数のDockerfileがある場合は、
Docker Composeを使うとまとめてDockerイメージを作成できます。
compose.yamlに各Dockerfileを指定します。
services:
web:
build: ./web # Dockerfile
app:
build: ./app # Dockerfile
worker:
build: ./worker # Dockerfile
ローカルPCのターミナルでcompose.yamlがあるディレクトリへ移動し、
以下を実行します。
docker compose build
これでWeb・App・WorkerのDockerイメージをまとめてbuildできます。
ローカルで起動確認する
作成したDockerイメージが正常に起動するか確認するため、
ECRへpushする前にローカルで起動します。
docker compose up
これでWeb・App・Workerをまとめて起動できます。
停止する場合は、
docker compose down
を実行します。
DockerイメージをECRへpushする
ECSで使用するDockerイメージをAWS上に保存するため、
ローカルで確認したDockerイメージをAmazon ECRへpushします。
例えばAppの場合は、ECRのRepositoryを作成したあと、
ローカルPCから以下のように実行します。
aws ecr get-login-password --region ap-northeast-1 \
| docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
docker tag my-app:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
ECRでDockerイメージが保存されているか確認する
DockerイメージがECRへ正常にpushされているか確認するため、
RepositoryのImagesを確認します。
Amazon ECR → Repositories → 対象Repository → Images
- Image tag → pushしたイメージのタグ
- Pushed at → pushされた日時
- Image URI → DockerイメージのURI
ECSのTask DefinitionにECRのイメージを指定する
ECSでECRのDockerイメージからコンテナを起動するため、
ECRでImage URIを確認してTask Definitionに指定します。
Image URIは、
Amazon ECR → Repositories → 対象Repository → Images
から確認します。
例えば、
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
というImage URIです。
Task Definitionは、
Amazon ECS → Task definitions → 対象Task Definition → Revision
から確認し、コンテナ設定の「Image URI」にECRで確認したImage URIを指定します。
Task Definitionでは、Dockerイメージ以外にも以下の起動設定を確認・設定できます。
- CPU・メモリ
- ポート
- 環境変数
- 起動コマンド
- ログ設定
ECSでコンテナが正常に起動しているか確認する
ECSへデプロイしたコンテナが正常に起動しているか確認するため、
ServiceとTaskを確認します。
必要な数のTaskが起動しているか確認するため、
ServiceではDesired tasksとRunning tasks、デプロイ状況を確認します。
Amazon ECS → Clusters → 対象Cluster → Services → 対象Service
- Desired tasks → 起動するように設定されているTask数
- Running tasks → 実際に起動しているTask数
- Deployment → デプロイ状況
起動したTaskが正常な状態か確認するため、
Taskではステータスや停止理由などを確認します。
Amazon ECS → Clusters → 対象Cluster → Tasks
- RUNNING / STOPPED → Taskの状態
- 起動しているコンテナ
- 使用しているTask Definition
- 停止理由
Terraformを使う場合
Terraformを使う場合は、
ECRやECSの設定をAWSコンソールから手動で作成する代わりに、
.tfファイルにAWSの構成を定義します。
例えば、次のように役割ごとにファイルを分けて管理できます。
terraform/
├── ecr.tf
├── ecs.tf
└── variables.tf
ecr.tfでは、ECR Repositoryを定義します。
resource "aws_ecr_repository" "app" {
name = "my-app"
}
ecs.tfでは、ECS Clusterを定義します。
resource "aws_ecs_cluster" "main" {
name = "my-cluster"
}
同じくecs.tfで、Task Definitionを定義します。
resource "aws_ecs_task_definition" "app" {
family = "my-app"
container_definitions = jsonencode([
{
name = "app"
image = "${aws_ecr_repository.app.repository_url}:latest"
}
])
}
ECS Serviceもecs.tfで定義できます。
resource "aws_ecs_service" "app" {
name = "my-app"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 1
}
Dockerイメージはこれまでと同じようにECRへpushします。
TerraformでECR Repositoryを作成すると、
Repository URIはaws_ecr_repository.app.repository_urlで参照できます。
そのため、上記のTask Definitionでは、
image = "${aws_ecr_repository.app.repository_url}:latest"
として、ECRのDockerイメージを指定しています。
AWSコンソールからImage URIをコピーして手動で指定する必要はありません。
まとめ
ローカルでDockerイメージを作成・確認し、
ECRへpushしてTask Definitionに指定し、
ECSでコンテナを起動・確認するという流れになります。