2020/7にdokcer-compose形式のyamlファイルからECSのタスク定義ができるようになったのですが、まだまだ実用している例が少なかったので、実際にwebアプリケーションのデプロイ時に作成した際の注意点を残しておきます。Fargateインスタンスタイプでの利用例となります。
前提
docker-compose形式のファイルでタスク定義する際には、下記のファイルが必要になります。
-
docker-compose.yml
- コンテナ定義を行うためのファイル。通常のDocker利用時とほとんど同じだが、一部ECSで対応していない項目があるため、ECS用に修正する必要がある。
-
ecs-params.yml
- docker-compose.ymlだけでは設定しきれないタスク、サービスの設定を行う。
設定例
今回作成したアプリケーションは、db, api(Django), nginx, vueの4コンテナで構成されます。
docker-compose.yml
version: '3'
services:
db:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- db_efs:/var/lib/postgresql/data
logging:
driver: awslogs
options:
awslogs-group: test
awslogs-region: ap-northeast-1
awslogs-stream-prefix: db
api:
image: [ECRのイメージURL]:[タグ名]
command: /bin/sh -c "
./entrypoint.sh;"
env_file:
- ./api/.env
ports:
- 8000:8000
logging:
driver: awslogs
options:
awslogs-group: test
awslogs-region: ap-northeast-1
awslogs-stream-prefix: api
vue:
image: [ECRのイメージURL]:[タグ名]
ports:
- "8080:8080"
logging:
driver: awslogs
options:
awslogs-group: test
awslogs-region: ap-northeast-1
awslogs-stream-prefix: vue
nginx: [ECRのイメージURL]:[タグ名]
image:
ports:
- 80:80
logging:
driver: awslogs
options:
awslogs-group: test
awslogs-region: ap-northeast-1
awslogs-stream-prefix: nginx
volumes:
db_efs:
ecs-params.yml
version: 1
task_definition:
task_execution_role: ecsTaskExecutionRole
ecs_network_mode: awsvpc
task_size:
mem_limit: 0.5GB
cpu_limit: 256
services:
db:
essential: true
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
api:
essential: true
depends_on:
- container_name: db
condition: HEALTHY
vue:
essential: true
nginx:
essential: true
depends_on:
- container_name: api
condition: START
efs_volumes:
- name: db_efs
filesystem_id: [EFS ID]
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "サブネットID"
- "サブネットID"
security_groups:
- "セキュリティグループ名"
assign_public_ip: ENABLED
注意点
下記の点に注意が必要です。
イメージの利用
ECSではdocker-coompose.ymlのbuild項目がサポートされておらず、必ずECRやdocker-hubにあるイメージをpullする形となります。
image: [ECRのイメージURL]:[タグ名]
コンテナ間の依存関係
ECSではdocker-composeでのdepends_onがサポートされていません。
代わりに、ecs-params.ymlに記載します。この際、コンテナ間の依存関係はヘルスチェックの状態に基づいて定義します。
api:
essential: true
depends_on:
- container_name: db
condition: HEALTHY
db:
essential: true
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
上記のように設定することで、dbコンテナでは起動時にヘルスチェックが行われ、dbコンテナがHEALTHY状態になってからapiコンテナが起動するという依存関係を定義することができます。
EFS Volumeの利用
Fargateインスタンスタイプで永続ボリュームを利用する際は、EFSをマウントさせる必要があります。
ecs-params.ymlで下記を記載することで、あらかじめ作成しておいたEFSをマウントさせることができ、
efs_volumes:
- name: db_efs
filesystem_id: [EFS ID]
下記のようにdocker-compose.ymlからvolumesを指定することができます。
services:
db:
image: postgres
volumes:
- db_efs:/var/lib/postgresql/data
volumes:
db_efs:
Cloudwatch Logsの利用
Cloudwatch Logsと連携させることで、コンテナのログを出力させることができます。
例えば、docker-compose.ymlのdbコンテナの設定で下記を記載することで、
testロググループが作成され、dbというprefixでログが記録されます。
db:
logging:
driver: awslogs
options:
awslogs-group: test
awslogs-region: ap-northeast-1
awslogs-stream-prefix: db
サービスのデプロイ
上記のファイルを用意した後は、下記コマンドでデプロイを行います。
この際に、ELBでターゲットとなるtargetGroupを指定しています。
ecs-params.ymlは、このファイル名にしておくとデフォルトで設定ファイルとして選択されます。
ecs-cli compose \
--file docker-compose.yml \
--project-name test service up \
--create-log-groups \
--cluster-config test \
--ecs-profile test-profile \
--target-groups targetGroupArn=[targetGroupのARN],containerName=vue,containerPort=8080 \
--target-groups targetGroupArn=[targetGroupのARN],containerName=nginx,containerPort=80