Dockerを使ったECSへのNodeアプリ展開

この記事ではNode.jsアプリケーションをビルドし、Amazon Elastic Container Registry (ECR)およびAmazon Elastic Container Service (ECS)を用いてAmazon Web Services (AWS)へ展開することについてお話しします。具体的に言えば、以下のような手順があります。
1) 環境構築
NodeとNpmodeについて こちら へアクセスしてから最新バージョンをインストールしてください。
Docker(ドッカー)について こちら へアクセスしてから最新バージョンをインストールしてください。
AWS アカウントについて無料アカウントを登録しておいてください。
AWS CLIについてこちらへアクセスしてから、お使いのOSに応じて手順を行ってください。
2) DockerおよびAWSの概要
Dockerとは、どこへもプッシュし、実行できるコンテナを用いてアプリケーションと依存関係や環境変数をビルドするためのオープンソースソフトウェアをいいます。Dockerではハードウェアやフラットフォームから隔離しているのでコンテナに入るアプリケーションをどんな環境にも独立的に実行することができます。
Amazon Web Services (AWS)は費用のかからない拡張可能かつ安全なクラウドサービスを提供します。前述の如く、この記事ではECRとECSのサービスについてのみお話しします。
3) Node.jsアプリ作成
以下のように展開のためのサンプルアプリケーションを予め作成しておいてください。簡単なNode.jsアプリケーションで良いです。
端末に以下のように入力します。
// 新たなディレクトリー作成
$ mkdir ecs-nodejs-app
// 作成したてのディレクトリーへの移動
$ cd ecs-nodejs-app
// npm初期化
$ npm init -y
// expressインストール
$ npm install express
// server.jsファイル作成
$ touch server.js
server.jsファイルを開いて、以下のコードをそこにコピー・ペーストします。
// server.js
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Welcome from a Node.js app!')
})
app.listen(3000, () => {
console.log('Server is up on 3000')
})
以下のコマンドでアプリケーションを起動します。
$ node server.js
ブラウザを開いて http://localost:3000 にアクセスすると、「Welcome from a Node.js app! 」が表示されます。
次の手順でアプリケーションをビルドします。
4) Dockerファイル作成
以下のように、ルートディレクトリーにDockerファイルというユニークなファイルを作成することによりアプリケーションをビルドします。なお、このファイルには拡張子がありません。
FROM node:8-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 3000
CMD [ "node", "server.js" ]
5. Dockerイメージのビルド
Dockerを設定して実行したことを確認してください。今やDockerファイルが作成済なので、以下のようにDockerイメージを「 -t 」コマンドでビルドします。
$ docker build -t ecs-nodejs-app .
6. Dockerコンテナ実行
これまで、Dockerイメージ作成の完了です。作成したDockerイメージを確認するために以下のコマンドを打ちます。
$ docker images
作成したてのDockerイメージは登録時間で一番新しいものです。

前もってイメージIDをコピーしておきます。コンテナを実行するために以下のコマンドを打ちます。
$docker run -p 80:3000 {image-id}
// コピーしたイメージIDを{image-id}に入れます。
ここで、ポート:80:3000へアプリケーションを展開します。Dockerをローカル実行するのでhttp: // localhost にアクセスして確認します。

7. レジストリ作成およびそこへのDockerイメージのプッシュ
Amazon Elastic Container Registry (ECR) は、完全マネージド型のコンテナレジストリです。このレジストリを使うと、コンテナイメージをどこにでも簡単に保存、管理、共有、デプロイすることができます。 Amazon ECR はAmazon Elastic Container Service (ECS)と連携して開発から本稼働までのワークフローを簡素化することができます。
Dockerイメージをプッシュする前に、以下のコマンドを実行して、AWS CLIが自分のAWSアカウントで接続できていることを確認してください。
$ aws configure
AWS CLIが既にインストールされた場合、AWS設定として以下の情報が求められます。
$ aws configure
AWS Access Key ID [None]: <accesskey>
AWS Secret Access Key [None]: <secretkey>
Default region name [None]: us-east-2
Default output format [None]:
AWS CLIが正確に設定されていることを確保するため、AWS設定コマンドを再度実行して、表示される確認プロンプトでエンターキー押下してください。

レジストリ作成の手順は以下の通りとなります。
まず、AWSマネジメントコンソール へアクセスし、ログインを行います。
つぎ、Servicesカテゴリーから、Containersの中にあるElastic Container Service(ECS)を選択します。

つぎ、左メニューのECRからはRepositoriesへ辿ってから、Create Repositoryメニューを選択した後に、リポジトリ名(例:"ecs-nodejs-app")を入力してCreate Repositoryボタンを押します。


つぎ、右上にあるView Push Commandsをクリックした時に表示される4つの手順どおりに、Dockerイメージをビルド、タグ作成し、プッシュします。

その後、Amazon ECRへ戻って、先ほど入力したリポジトリ名をクリックするとDockerイメージが見えます。 次の手順に使うので、そのイメージのURIをコピーしておいてください。
次の手順で、 EC2インスタンスでDockerイメージを実行するために使われるTask Definitionというタスク定義)、Clusterというクラスター、Serviceというサービスを作成します。
8. タスク定義の作成
AWSでのタスクはDocker CLIでのDocker実行コマンドのように機能しており、以下のように定義されています。
- Container images
- Volumes
- Networks Environment Variables
- Port mappings
以下に、タスク定義の作成手順を示します。
1. ESCダッシュボードにあるTask Definitionsより、Create new Task Definitionを押下
2. Launch TypeでEC2を選択
3. タスク名(例:"ecs-nodejs-app-task")を入力してから他の項目を飛ばして、下部へ辿ってAdd containerを押下
4. コンテナ名(例:"ecs-nodejs-app-container")を入力
5. 前の手順でコピーしておいたイメージのURIをImageにペースト
6. Memory Limitsで"Soft Limit"を選択し、適当な値を(例:"512")を入力
7. Port Mappingで、各ポートを"80: 3000"で入力、プロトコルを"tcp"と選択
8. Environment Variablesへ辿って、Keyに"NODE_ENV"、Valueに"production"を入力
9. 他の項目を飛ばして一番下にあるAddを押下
10. Create Task Definition画面へ戻し、対象のコンテナとDockerイメージが表示され、下部へ辿ってCreateを押下

9. クラスターの作成
以下に、クラスターの作成手順を示します。

1. ServicesカテゴリーよりECSを押してECSダッシュボードへ戻す
2. 左メニューよりAmazon ECS(EKSではない)の直下にあるClustersをクリックしてCreate Clusterを押下
3. クラスター・テンプレートとしてEC2 Linux + Networkingを選択してNext Stepを押下
4. クラスター名(例:"ecs-nodejs-app-cluster")を入力
5. EC2 Instance Typeでデフォルトのままにするか"t2.micro"を選択
6. Number of instancesに"1"、EBS Storageに"30"を入力
7. Key pairでデフォルトのままにするか、対象のEC2インスタンスへSSHしたい場合の既存キーを選択
8. VPCでCreate a new VPCを押して新規作成して、下部へ辿る
9. Container instance IAM roleで作成した権限(例:"ECStoEC2role")を選択してCreateを押下

処理に数分がかかります。終わったらView Clusterを押下することで、Active状態が見えます。
10. クラスター実行用サービスの作成
この手順で、クラスターを実行するためのサービスを作成します。

以下に、サービスの作成手順を示します。
1. 左メニューのECSよりTask Definitionを押してから、定義したタスク(例:"ecs-nodejs-app-task")を選択
2. 最新版を選択
3. Create new revisionの横にあるActionカテゴリーよりCreate Serviceを選択
4. Configure Serviceページで、Launch typeでEC2を選択
5. Clusterで作成したクラスター(例:"ecs-nodejs-app-cluster")を選択
6. サービス名(例:"ecs-nodejs-app-service")を入力
7. Number of Tasksに "1"を入力
8. 他の項目や次のページを飛ばして、4ページへと移動してから下部へ辿ってCreate Serviceを押下
9. Launch Statusページで、作成したサービスに緑チェックマークが入る。View Serviceを押した後に、TasksタブのLast Statusが"PENDING"であるならば、少し時間が経過し、または、再描画アイコンをクリックすることで"RUNNING"になる

ClusterからEC2 instancesタブで対象のインスタンス・コンテナを押すことで公開DNSリンクを生成します。


ブラウザーでその公開DNSへアクセスすると、作成したアプリが開きます。
ec2-52-193-75-195.ap-northeast-1.compute.amazonaws.com

Githubからサンプルソースを参考にしましょう!
参考元
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/getting-started.html
https://blog.clairvoyantsoft.com/deploy-and-run-docker-images-on-aws-ecs-85a17a073281