OpenProjectが公開しているdocker-compose.ymlをAWS ECSにデプロイしてみました その2
以前OpenProject on AWS ECSという記事で、ecs-cliを使ってECSにOpenProjectをデプロイしてみたんですが、今回は同じことをdockerのECS拡張を使ってやってみました。
OpenProjectのもともとの構成ではmemcachedとpostgresqlもコンテナ動作させてますが、そこは個人の趣味でマネージドサービスを使用しています。
dockerのECS拡張とは
2020/7に発表された拡張機能です。AWS and Docker collaborate to simplify the developer experienceにあるとおり、dockerクライアントで直接ECS上のコンテナを操作できるという代物です。docker-composeも使用可能になってます。
2020/11/19にGA到達しました。Docker Compose for Amazon ECS Now Available
以前のデプロイ方法(ecs-cli)の困ったところまとめ
- ecs-cliがdocker-composeのver3.xに対応していないため、凝った作りのdocker-compose.ymlの場合はかなりの部分を編集しなければならない
- fargateへのデプロイが困難
- コンテナ間依存の記述が困難
コマンド実行環境インストール概要
Deploying Docker containers on ECSの通り作業して、コマンド実行環境を作ります。
awscli
Ubuntu 20.04でコマンド実行環境を作りました。まずaws cliをインストールし、credential設定します。
なお、以下のIAM権限が必要でした。
- EC2
- IAM
- ElasticLoadBalancing
- CloudMap
- ElasticFileSystem
- CloudFormation
その他に、以下の権限も与えてましたが、docker compose upに必要かどうかは未確認です。
- ECS
- CodeDeploy
- CloudWatchLogsFullAccess
docker-cli
docker-ceおよびdocker-composeをインストールしました。
マニュアルにあるとおり、AWS contextを設定してやる必要があります。
その他AWS環境
postgresqlとmemcached
リージョン内にpostgresqlとmemcachedのマネージドサービスを作成しておきます。postgresqlのユーザとパスワードは、docker-compose.yml記載のものをそのまま使って作成しました。
接続先情報はdocker-compose.ymlに記述します。
default VPC
default VPCがリージョンに存在している必要があります。普通あるとは思いますが、何かの理由で消してしまった場合は作成しておいてください。
docker-compose-yml
dockerのECS拡張では、docker-compose.ymlファイルをcloudformationに食わせるように変換して、cloudformation経由でECS環境を作るということをやっています。
まず、OpenProjectのマニュアル通りdocker-compose.ymlファイルを入手します。
> git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/11 openproject
このファイルに対して修正します。
最終的に使用したdocker-compose.ymlは以下の通りとなりました。
version: "3.7"
networks:
frontend:
backend:
volumes:
opdata:
x-op-restart-policy: &restart_policy
restart: unless-stopped
x-op-image: &image
image: openproject/community:${TAG:-11}
x-op-app: &app
<<: *image
<<: *restart_policy
environment:
RAILS_CACHE_STORE: "memcache"
OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache.yyyy.cfg.usw2.cache.amazonaws.com:11211"
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
DATABASE_URL: "postgres://postgres:p4ssw0rd@openproject.xxxxx.us-west-2.rds.amazonaws.com/openproject"
USE_PUMA: "true"
# set to true to enable the email receiving feature. See ./docker/cron for more options
IMAP_ENABLED: "${IMAP_ENABLED:-false}"
volumes:
- "opdata:/var/openproject/assets"
services:
proxy:
<<: *image
<<: *restart_policy
command: "./docker/proxy"
ports:
- "${PORT:-8080}:80"
environment:
APP_HOST: web
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
depends_on:
- web
networks:
- frontend
web:
<<: *app
command: "./docker/web"
networks:
- frontend
- backend
deploy:
resources:
limits:
cpus: '0.5'
memory: 2048M
worker:
<<: *app
command: "/bin/sh -c './docker/worker && /bin/sh'"
networks:
- backend
cron:
<<: *app
command: "./docker/cron"
networks:
- backend
3.7の記法をそのまま使えるため、大幅に楽になりました。
オリジナルとの差分は以下の通りです。
- dbコンテナ削除に伴う対応
- volume削除
- 接続先設定変更
- 依存関係でのdb削除
- service dbの削除
- cacheコンテナ削除に伴う対応
- 接続先設定変更
- 依存関係でのcache削除
- service cacheの削除
- seederコンテナ削除に伴う対応
- service seederの削除
- 依存関係でのseeder削除
- essential設定が出来ないことへの対応
- workerコンテナのコマンドを修正
- webコンテナの使用リソース設定
- CPUとメモリの設定を追加
下の3つについて説明します。
「seederコンテナ削除に伴う対応」
seederコンテナというのは、compose up時に動作してDBの初期化を行ったのち、常駐せずにexitするコンテナです。
ECS環境ではこういうコンテナにはessential = falseという設定を入れてやらないといけないのですが、docker-compose.ymlへのessential設定の方法がマニュアルやサンプルで説明されていません。
また、seederがモタモタ動いているうちに環境全体が終了してしまうという事態が頻発したため、DB設定のためseederだけ動かすdocker-compose.ymlを作成したあと、上に引用のdocker-compose.ymlを使って最終的な環境を作るということにしました。
「essential設定が出来ないことへの対応」
上述の通り、seederコンテナは常駐しないのですが、他にもそういう動作をしているらしきコンテナ(worker)がいます。終了してしまわないように、コマンドに手を入れています。(不要かもです)
「webコンテナの使用リソース設定」
デフォルトで各コンテナはCPU 256ms/Memory 512MBというlimit設定で起動してきますが、これだとWebコンテナがまともに動作しなかったため、このコンテナだけは多めにリソースを積みました。記法はサンプルの通りです。
その他
環境変数
デフォルトではproxyコンテナは8080番をbindしているんですが、fargateでは?動作しませんでしたので、docker compose up実行時に以下の環境変数を設定して、コンテナと同一ポートを使用するようにしました。
> set -x PORT 80
コンバート
cloudformationに食わせているファイルは、以下の方法で確認できます。
> docker compose convert
まとめ
オリジナルに対してかなり手をいれてますが環境設定のための編集がほとんどで、基本的には3.x記法をそのまま使えるためecs-cliを使うよりはかなり楽になりました。
以前のデプロイ方法の困ったところまとめはクリア出来てます。
docker-compose.ymlを使ってECSにサービスをデプロイしたい場合はぜひ試してみてください。