ECSでPHPのDocker Imageを動かすときの注意点
発生したこと
ローカルで動かしていたPHP + Nginx + Mysqlの3層webアーキテクチャのDockerコンテナをECS + Faragte構成で動かそうとデプロイしたところ動かない。。
Nginxは問題なさそう。じゃあPHPかと思ってlogと睨めっこしていたところ、どうやらdocker-php-entrypointがローカル環境では動いていたっぽいが、デプロイ後は動いていないということがわかりました。
ENTRYPOINT ["docker-php-entrypoint"]
原因
migrationを実行しようとECSのタスク定義でENTRYPOINTの設定をしたのですが、Dockerの仕組み上ENTRYPOINTやCMDは最後に実行したものしか動かない。つまりmigrationの処理で上書きをしてしまって、本来動いていたdocker-php-entrypointが動かなくなったのが原因でした。
ローカルではコンテナの起動時にmigrationを実行するとかしないから、わからなかった。。
解決方法
本来のdocker-php-entrypointとmigrationの実行を両方すれば良いので、解決方法としては2パターンあります。
shellスクリプトなどを作り、その中で実行する
こちらの記事に詳しく書いてます。
migrationを実行するコンテナを用意する
今回はこの方法で実装しました。
同じPHPのイメージを使うのですが、migration用のコンテナはmigrationを実行後停止しても良いのでdocker-php-entrypointの処理は動かなくて問題無し。
PHPのコンテナは動かしたいので、docker-php-entrypointを実行させておく。
ECSのタスク定義はこんな感じ。ECSのタスク定義の細かい説明は割愛します。
[
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/NGINX-prod",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs",
"awslogs-datetime-format": "%Y-%m-%d %H:%M:%S"
}
},
"entryPoint": null,
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
],
"command": [],
"linuxParameters": null,
"cpu": 0,
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/nginx",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "NGINX"
},
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/APP-prod",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs",
"awslogs-datetime-format": "%Y-%m-%d %H:%M:%S"
}
},
"entryPoint": null,
"workingDirectory": null,
"portMappings": [
{
"hostPort": 9000,
"protocol": "tcp",
"containerPort": 9000
}
],
"command": [],
"linuxParameters": null,
"cpu": 0,
"environment": [
// DB_PORTとか設定する
],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/app",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "APP"
},
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/APP-prod",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs",
"awslogs-datetime-format": "%Y-%m-%d %H:%M:%S"
}
},
"entryPoint": null,
"workingDirectory": "/work/backend",
"portMappings": [
{
"hostPort": 9001,
"protocol": "tcp",
"containerPort": 9001
}
],
"command": [
"php",
"artisan",
"migrate:fresh",
"--force",
"--seed"
],
"linuxParameters": null,
"cpu": 0,
"environment": [
// DB_PORTとか設定する
],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/app",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": false,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "MIGRATE"
}
]
重要なのはここですね。migrationのコンテナは停止しても、タスク自体は動かし続けたいのでessentialはfalseにしておきます。
"essential": false,
いやー、ECS + Fargateの構成は難しい。。
いろんなところで躓くので、早く知見をもっとためたいな。
Discussion