Copilot CLI で Fargate にデプロイした Laravel コンテナと Nginx コンテナのファイル共有
AWS Copilot CLI を使用して Laravel フレームワークで開発した PHPアプリケーション を Fargate にデプロイする際に私自身が困ったことを中心に記したいと思います。
まず今回やりたかったことについて説明します。
Nginx と Laravel のコンテナをデプロイして同じ Fargate タスクに含めたいという状況で、Nginx のコンテナはサイドカーで実行する形を取ります。(構成についてはもう少し考えたい部分はありますがご了承ください。)
まず Laravel のコンテナイメージを ECR にアップロードする必要があります。その際に、 composer install, npm install などいくつか処理したい内容が Dockerfile に記載されていました。
そして、Nginx のコンテナイメージを ECR にアップロードして、Laravel と Nginx の2つのコンテナを同じタスクとして Copilot CLI でデプロイします。
Nginx に来た静的なコンテンツに関しては、 nginx.conf の root で指定した /var/www/html/public
から直接返したいと思います。
1 2 3 4 5 6 7 |
server { listen 80; server_name example.com; root /var/www/html/public; ~~~ } |
そこで、Laravel コンテナのボリューム /var/www/html/public
を Nginx に共有する方法を取ることにしました。
ボリュームソースとして Laravel コンテナを指定し読み取りができるように Nginx コンテナ側にバインドマウントさせます。
実は以上のことを Fargate で実現する事自体は特に難しい話ではありません。
( ここまでの構成や設定については、ユニファ株式会社さんの 開発者ブログの記事 がとても丁寧にまとめてくれていますので参考にしてください。 )
では今回どこで苦労したかというと、これをどのように Copilot のマニフェストで実現すればよいのかというところでした。( Nginx のコンテナイメージをビルドする際に Laravel コンテナ同様にアプリケーションを含めるということも可能ですが、殆ど変更のない Nginx のコンテナイメージを毎回 Laravel のアプリを更新するためだけにビルドしてアップロードするのは大変ですし、イメージサイズの肥大にもなり、無駄が多くとても Bad な手段・アーキテクチャとなってしまいます。)
ちなみに、マウントポイントに関してはドキュメントに方法が記載されていますが、ボリュームソースの設定に関しては記載がありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
storage: ephemeral: 100 volumes: scratch: path: /var/data read_only: false sidecars: mySidecar: image: public.ecr.aws/my-image:latest mount_points: - source_volume: scratch path: /var/data read_only: false |
今回は下図のようになることが目標です。
解決策: Copilot マニフェストの書き方
さっそくどのようにすべきかについてですが、対応していないものは taskdef_overrides というセクションを利用するのがよいことが分かりました。
ECSタスク定義に関するドキュメントや、実際に動いているコンテナの定義をコンソールから確認することで、変更すべき項目が "ContainerDefinitions[1].VolumesFrom[-]"
であることが分かりました。
“ContainerDefinitions[1].VolumesFrom[-]”
ちなみに以下のようなこともあったので、 copilot svc package
コマンドでも確認した方がよさそうです。
copilot svc package コマンド大事。volumesFromがself loop detected でなんでだろうって思ってたらコンソールからみたjsonのタスク定義の並びとは違ってcontainerDefinitions[1]だった
— すこぶる (@Scble) February 27, 2023
オーバーライドすべき項目がわかったので以下のマニフェストを実行し、上図 “コンテナのボリューム設定” のようにボリュームソースとしてソースコンテナを Laravel コンテナに指定することができました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
name: laravel-app type: 'Load Balanced Web Service' image: build: dockerfile: laravel-app/docker/php/Dockerfile target: dev context: laravel-app port: 9000 sidecars: nginx: port: 80 image: xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxxxxxx/nginx:latest depends_on: castee-web: start # ~~~~ 一部割愛 ~~~~ taskdef_overrides: - path: "ContainerDefinitions[1].VolumesFrom[-]" value: SourceContainer: "laravel-app" ReadOnly: true |
さいごに
よくドキュメントを読んでいれば taskdef_overrides についても気づけましたが… 今回は以上となります。
余談:AWS Copilot CLI は Pipeline や Schedule Job の作成、シークレットマネージャーとの連携、 App Runner の作成などにも対応していますし、開発がしっかり進められているので今後にも期待です。
Github: aws/copilot-cli