Docker composeとAWS(ECR/ECS)デプロイ
React・DockerとAWS
みなさんDockerは使っているだろうか。
私は恥ずかしながら業務では使用していない。
だが、今回(2020/09)非常に興味深いdocker compose
とECS統合という物が実装された。
Docker Compose for Amazon ECS Now Available
平たくいうと、dockerとAWSの連携コマンドなのだが
※docker compose
はdocker-compose
コマンドのdocker cli版である。
今後はdoker cliを使用してね。という事だそうだ。
この魔法のようなコマンドはdockerのコマンドを使うことで自動でAWSにデプロイしてしまう。
という凄まじい物だった。
私としても備忘録にするため、筆を取った次第だ。
前提条件
実際にDockerを使用している皆様にはもう十分だろう。
随時参考リンクがあるので見てくれると嬉しい。
( ※もし、詳しく聞きたいというコメントしてくれれば対応するかもしれないね:) )
- AWSアカウントの作成とCLIのインストール
- Dockerインストール
- Docker
- Dockerfile、docker-compose.ymlの作成
- Dockerイメージのビルド
- コンテナの起動とReactの実行
- docker Compose でデプロイ
AWSアカウントの作成
AWSアカウントについては今更述べる必要は薄いとは思う。
やりたい事はIAM Userの作成なのだが、以下に私が昔参考にしたブログを載せておく
※上記の情報は古いが、ここで重要なのはどんなワードを元に検索するか?だ。
Dockerインストール
Dockerには様々なチュートリアルが存在している。
後で詳しく説明するがlinuxベースの仮想環境である。
と言えば少しは荷が軽くなったような気がする。
以下のサイトが参考になるかと思う。
Docker入門:Docker概要,基本操作,マウント,Dockerfile,マルチステージビルド
Dockerfile、docker-compose.ymlの作成
ここは重要なフェーズの一つだ。
docker compose
コマンドの名が示す通り
docker-compose
コマンドの亜種だ(同じコマンドではないので注意だ。)
なので複数コンテナが使う事を想定されている。
ここでcomposeをいまいち分かってない人は以下のブログを参考にすると良いだろう。
Docker Composeとは
さて、今回はapi用のDockerと、front用のDockerを用意する
Dockerfile.api
# ベースイメージの作成
FROM node:14.15.1-buster
# コンテナ内で作業するディレクトリを指定
WORKDIR /usr/src/app
# package.jsonとyarn.lockを/usr/src/appにコピー
COPY ["./api/package.json", "./api/yarn.lock", "./"]
RUN yarn install
# ファイルを全部作業用ディレクトリにコピー
COPY ./api .
# ポートのエクスポート
EXPOSE 9999
CMD yarn start
Dockerfile.front
# ベースイメージの作成
FROM node:14.15.1-buster
# コンテナ内で作業するディレクトリを指定
WORKDIR /usr/src/app
# package.jsonとyarn.lockを/usr/src/appにコピー
COPY ["./front/package.json", "./front/yarn.lock", "./"]
RUN yarn install
# ファイルを全部作業用ディレクトリにコピー
COPY ./front .
# ポートのエクスポート
EXPOSE 3000
CMD yarn start
以下の2つのDockerを纏めるdocker-compose.yml
を用意する。
- Dockerfile.api
- Dockerfile.front
docker-compose.yml
version: "3"
services:
frontend:
image: soreiyu/front
build:
context: .
dockerfile: Dockerfile.front
command: "yarn start"
ports:
- "3000:3000"
volumes:
- ./front:/usr/src/app
tty: true
api:
image: soreiyu/api
build:
context: .
dockerfile: Dockerfile.api
command: "yarn start"
ports:
- "9999:9999"
volumes:
- ./api:/usr/src/app
上記は以下を参考にしているため、以下のサイトを参考に、まずは普通にコンテナ起動をしてみよう。
※あとでdocker contextというものを変更するが、ローカル環境はdefaltでないと動かないので気を付けよう
DockerのNodeをどれにするか?
Dockerのその他
コンテナの起動とReactの実行
ここまで出来ていれば以下のコマンドで一発だ。
docker-compose up
付録 Dockerでbabelのwatch機能が利かない
私がDockerでreactの開発をしているときに
自動でトランスパイルされない自体に陥った。
以下.env
ファイルを作成する事により
watch機能を有効にしたことで解決した。
.env
CHOKIDAR_USEPOLLING=true
babelのwatch機能がdockerコンテナ上で動かない
docker Compose でデプロイ
さて、以下のようなファイル構成になったと思う。
dockerProject
├─api ← api用プロジェクト
├─front ← front用プロジェクト(react)
│ └─.env ← react用のenvファイル
├─Dockerfile.api ← api用のDockerfile
├─Dockerfile.front ← front用のDockerfile
└─docker-compose.yml ← compose用のymlファイル
いよいよAWSにデプロイする。
今回使用するAWSサービスは以下の二つだ
-
ECR(Amazon Elastic Container Registry)
- AWS版のDockerHUBのような物だ。Dockerファイルのホスティングサービスだ
-
ECS(Elastic Container Service)
- 完全マネージド型のコンテナオーケストレーションサービスだ。
大まかな流れとしてはECRにpushしたものをECSで公開するという流れだ
(※別段ECRで管理する必要はないが、AWSの認証の関係でECR,ECSの連携の方が楽なため、この方式にしている)
以下のコマンドを使用し、まずはコマンドラインのawsのログインをしよう。
aws ecr get-login-password | docker login --username AWS --password-stdin https://<aws_account_id>.dkr.ecr.<region>.amazonaws.com
参考資料
AWS CLIでECRにログインする時はget-loginではなくget-login-passwordを使おう
docker-compose コマンドでECRにpush
さて、次にECRに今回作成したdocker imageをpushしたい。
その為にまずはAWSでレポジトリを作成しよう
ここでプライベートレポジトリにしないと、コマンドで使用できないため、プライベートにしよう。
次にymlファイルのpush先を変更しなければならない。
これは、AWSのプッシュコマンドを表示というところをクリックすれば細かい詳細がみれるので
そこから使用すればよいだろう。
docker-compose.yml
version: "3"
services:
frontend:
# image: soreiyu/front
image: 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/soreiyu/front
build:
context: .
dockerfile: Dockerfile.front
command: "yarn start"
ports:
- "3000:3000"
volumes:
- ./front:/usr/src/app
tty: true
api:
# image: soreiyu/api
image: 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/soreiyu/api
build:
context: .
dockerfile: Dockerfile.api
command: "yarn start"
ports:
- "9999:9999"
volumes:
- ./api:/usr/src/app
dockerをbulidしtag名を付けて以下のコマンドで実際にpush出来るかためそう。
tag名に関しては、細かい詳細で確認しよう
docker-compose push
※私がここで良く失敗するのは
docker context を default
以外にしてしまっている時だ。
さて実際にECRレポジトリにpushされたか確認しよう
aws ecr describe-repositories
これで以下のような表示がされれば無事push出来ている
(※パブリックだとこのコマンドで表示されない。)
{
"repositories": [
{
"registryId": "012345678910",
"repositoryName": "ubuntu",
"repositoryArn": "arn:aws:ecr:us-west-2:012345678910:repository/ubuntu"
},
{
"registryId": "012345678910",
"repositoryName": "test",
"repositoryArn": "arn:aws:ecr:us-west-2:012345678910:repository/test"
}
]
}
docker compose
魔法のさて、ここまできてようやく下地が整った。
今回追加されたdocker compose
コマンドを使用しよう
以下の通りにAWS コンテキストの生成を行う。
ECS での Docker コンテナーのデプロイ
次にAWSコンテキストを以下コマンドで使用しよう。
docker context use myecscontext
今なんのcontextを使用しているかは以下コマンドで確認できる。
docker context ls
そして次に重要なのはcompose ymlファイルの編集だ。
compose コマンドは対応していないルールがあるので、そこだけコメントアウトする必要がある。
(※消しても良いが、コメントを外したりする機会があるかと思うので私はこうしている。)
docker-compose.yml
version: "3"
services:
frontend:
# image: soreiyu/front
image: 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/soreiyu/front
# build:
# context: .
# dockerfile: Dockerfile.front
command: "yarn start"
ports:
- "3000:3000"
# volumes:
# - ./front:/usr/src/app
# tty: true
api:
# image: soreiyu/api
image: 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/soreiyu/api:latest
# build:
# context: .
# dockerfile: Dockerfile.api
command: "yarn start"
ports:
- "9999:9999"
# volumes:
# - ./api:/usr/src/app
さて、以下コマンドを祈りながら発行しよう。
docker compose up
うまく出来ていればAWSで公開されている。
では最後に一括完全消去して終わりにしよう。
docker compose down
ここまで読んでくれてありがとう。
良いDockerライフを!;)
エラーになったときの対処
クラスターが作成されない → route53のサービスが中途半端に削除されているなど
Discussion