前回からの続きで Express の前段に nginx を配置する構成を Copilot のサイドカーパターンを使って構築する方法を紹介します。
サイドカーパターンとは
コンテナのデザインパターンの 1 つで、メインとなるコンテナを拡張・補完する目的で別のコンテナを配置することです。 その名の通りバイクの横についてるサイドカーが由来になっているそうです。
参考1: Sidecars - AWS Copilot CLI
参考2: https://dl.acm.org/doi/10.5555/3027041.3027059
前提
前回の記事からの続きとして AWS Copilot で Express がデプロイされている状態から始めます。
nginx の準備
前回のディレクトリ構造に nginx を追加して以下のようにしていきます。
copilot-express ┣ copilot ┃ ┣ api ┃ ┃ ┗ manifest.yml ┃ ┗ .workspace ┣ nginx ←これから作成 ┃ ┣ Dockerfile ┃ ┗ nginx.conf ┣ Dockerfile ┣ index.ts ┣ package.json ┗ tsconfig.json
nginx の作業用ディレクトリを作成
$ mkdir nginx && cd nginx
nginx.conf の作成
$ touch nginx.conf
server { listen 80; location / { proxy_pass http://localhost:3000; } }
ここで localhost:3000
を指定する理由は Fargate タスクはawsvpc networking mode
と呼ばれる通信方式で動作しており、同一タスクに属するコンテナ間は localhost
でのアクセスが可能なためです。
参考 1: Task Networking in AWS Fargate | AWS Compute Blog
参考 2: More detailed example for the nginx sidecar use case · Discussion #2674 · aws/copilot-cli · GitHub
Dockerfile の作成
$ touch Dockerfile
FROM nginx:alpine RUN rm -f /etc/nginx/conf.d/* ADD nginx.conf /etc/nginx/conf.d/nginx.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
Docker イメージの作成
$ docker buildx build --platform=linux/amd64 -t copilot-express/nginx . $ docker images | grep copilot-express/nginx
docker buildx
を使う理由は、M1 Mac 上でdocker build
で作成したイメージだとデプロイ時にstandard_init_linux.go:228: exec user process caused: exec format error
が発生してタスクの起動に失敗するためです。
具体的には M1 Mac (arm64)と Fargate(Linux のデフォルトは x86_64) の CPU アーキテクチャが異なるため発生しており、対策として docker buildx
を使用してビルドしています。
参考: node.js - 'exec user process caused: exec format error' in AWS Fargate Service - Stack Overflow
ECR リポジトリの作成 & プッシュ
前回copilot init
で作成された ECR リポジトリ名がcopilot-express/api
だったので、 今回はcopilot-express/nginx
という名前で ECR リポジトリを作成します。
$ aws ecr create-repository --repository-name copilot-express/nginx
タグをつけてプッシュします。
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com $ docker tag copilot-express/nginx:latest xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/copilot-express/nginx:latest $ docker push xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/copilot-express/nginx:latest
これで nginx の準備が完了です。
Copilot Manifest の修正 & デプロイ
./copilot/api/manifest.yml
の修正
前回のcopilot init
で作成された ./copilot/api/manifest.yml
に 以下のように追記します。
http: # 追加 targetContainer: nginx # 追加 sidecars: nginx: port: 80 # ECR にプッシュした nginx イメージの URI を指定 image: xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/copilot-express/nginx:latest
ECS デプロイ
./copilot/api/manifest.yml
への追記が完了したらデプロイを実行します。
$ copilot svc deploy ~~~~~ ✔ Deployed service api. Recommended follow-up action: - You can access your service at http://xxxxx.ap-northeast-1.elb.amazonaws.com over the internet.
表示された URL にアクセスして前回同様 Express app works!
が表示されたらサイドカーパターンでのデプロイ完了です。
構成の確認
マネジメントコンソールの ECS > クラスター > copilot-express-test-Cluster-xxxxx
(copilot init
で作成されたクラスター) > タスクから、api
とnginx
のコンテナがRUNNING
になっていることが確認できます。
また EC2 > ロードバランサー > 対象のロードバランサー > リスナータブ > 転送先からポートが 3000
だったのが 80
に変わっていることが確認できます。
リソースの削除
各種構成や動作確認ができたので、Copilot で作成したリソースを削除します。
$ copilot app delete
ECR の copilot-express/nginx
リポジトリは AWS CLI から作成したので個別で削除します。
$ aws ecr delete-repository --repository-name copilot-express/nginx --force
まとめ
we are planning to support using local images or Dockerfiles.
と、公式ドキュメントにあるのでローカルのコンテナ環境をそのまま Copilot で ECS にデプロイできる日も近そうです!