Posted at
CureAppDay 7

AWS Elastic Beanstalk に Docker マルチコンテナで複数アプリケーションをデプロイ

More than 1 year has passed since last update.

この記事は CureApp Advent Calendar 2016 7日の記事です。

今日は Elastic BeanstalkDocker (ECS) で複数アプリをデプロイする話です。


目的

ひとつの Elastic Beanstalk に複数のアプリケーションを入れたら、

インスタンスの節約になったりするかも。

という動機のもとで、以下のような構成を検討しました。

Screen Shot 2016-11-16 at 18.12.03.png


前提条件


  • aws アカウント

  • node, docker, docker-compose インストール (ローカル確認用なので必須ではないです)


手順


1. テスト用アプリケーション作成

node で表示するだけのアプリケーションを作成。


node-app1/package.json

{

"name": "node-app1",
"version": "1.0.0",
"description": "sample node app 1",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "",
"license": "ISC"
}


node-app1/server.js


var http = require('http')
var server = http.createServer()

server.on('request', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'})
res.write('<h1>Hello my first application!</h1>')
res.end()
})

server.listen(80)
console.log('server listening...')


$ sudo npm start

同様に表示を少し変えて node-app2 も作成しました。


2. nginx の設定


proxy/conf.d/default.conf

server {

listen 80;
server_name localhost;

location / {
proxy_pass http://node-app1;
}

location /second/ {
proxy_pass http://node-app2;
}
}


通常は server_name とかで分けると思いますが、テストを簡単にするため、url で分岐させています。


3. docker compose で動かしてみる

試しに docker compose を使ってローカルで動かしてみました。


docker-compose.yml

version: '2'

services:
node-app1:
image: node:6.9.1-slim
volumes:
- ./node-app1:/usr/src/app
working_dir: /usr/src/app
command: npm start

node-app2:
image: node:6.9.1-slim
volumes:
- ./node-app2:/usr/src/app
working_dir: /usr/src/app
command: npm start

nginx-proxy:
image: nginx
volumes:
- ./proxy/conf.d:/etc/nginx/conf.d
ports:
- "80:80"
links:
- node-app1
- node-app2


.

├── docker-compose.yml
├── node-app1
│   ├── package.json
│   └── server.js
├── node-app2
│   ├── package.json
│   └── server.js
└── proxy
└── conf.d
└── default.conf

$ docker-compose up

ブラウザから確認。

http://localhost/first

http://localhost/second

今回は node:6.9.1-slim を使いましたが、実際は Docker Hub にあげて使う感じでしょうか。

Elastic Beanstalk 複数コンテナ環境では Dockerfile は使えないらしい。。(公式サイト)


4. アップロードファイル作成

公式サイトと docker-compose.yml を見比べながら、Dockerrun.aws.json を作成しました。


Dockerrun.aws.json

{

"AWSEBDockerrunVersion": 2,
"volumes": [
{
"name": "node-app1-src",
"host": {
"sourcePath": "/var/app/current/node-app1"
}
},
{
"name": "node-app2-src",
"host": {
"sourcePath": "/var/app/current/node-app2"
}
},
{
"name": "nginx-proxy-conf",
"host": {
"sourcePath": "/var/app/current/proxy/conf.d"
}
}
],
"containerDefinitions": [
{
"name": "node-app1",
"image": "node:6.9.1-slim",
"essential": true,
"memory": 128,
"mountPoints": [
{
"sourceVolume": "node-app1-src",
"containerPath": "/usr/src/app",
"readOnly": true
}
],
"workingDirectory" : "/usr/src/app",
"command": ["npm", "start"]
},
{
"name": "node-app2",
"image": "node:6.9.1-slim",
"essential": true,
"memory": 128,
"mountPoints": [
{
"sourceVolume": "node-app2-src",
"containerPath": "/usr/src/app",
"readOnly": true
}
],
"workingDirectory" : "/usr/src/app",
"command": ["npm", "start"]
},
{
"name": "nginx-proxy",
"image": "nginx",
"essential": true,
"memory": 128,
"portMappings": [
{
"hostPort": 80,
"containerPort": 80
}
],
"links": [
"node-app1",
"node-app2"
],
"mountPoints": [
{
"sourceVolume": "nginx-proxy-conf",
"containerPath": "/etc/nginx/conf.d",
"readOnly": true
},
{
"sourceVolume": "awseb-logs-nginx-proxy",
"containerPath": "/var/log/nginx"
}
]
}
]
}

このあと作成する zip がホストの /var/app/current に解凍されます。

essentialは、true に設定されたコンテナが止まると他のコンテナもすべて止まるという設定。(公式サイト)

.

├── Dockerrun.aws.json
├── node-app1
│   ├── package.json
│   └── server.js
├── node-app2
│   ├── package.json
│   └── server.js
└── proxy
└── conf.d
└── default.conf

圧縮します。

$ zip -r apps.zip Dockerrun.aws.json node-app1 node-app2 proxy


5. デプロイ

AWS Elastic Beanstalk コンソールからアプリケーションを作成。

項目
入力値

環境
ウェブサーバー環境

アプリケーション名
任意

プラットフォーム
Multi-container Docker

アプリケーションコード
作成した apps.zip をアップロード

表には記載していませんが、[さらにオプションを設定] → [セキュリティ] → [キーペア]を設定すると、

ホストに SSH で入れるようになります。


6. 完成!

作成後、無事ブラウザからアクセスできました。

http://******.elasticbeanstalk.com/first

http://******.elasticbeanstalk.com/second

EC2 Container Service のコンソール画面から確認。

Screen Shot 2016-11-28 at 13.58.53.png

SSH でホストに入って確認。

$ sudo docker ps

Screen Shot 2016-11-28 at 14.00.53.png


感想

以外にすんなり動きました。

最初に作成する際は、docker compose でやってみると、前もって動作確認ができるのと、Dockerrun.aws.json も作成しやすくなるのでいいです。

リソースの問題などいろいろ考慮する必要があると思うので、実際に使えるかどうかは、まだなんとも。。

明日は、@kt3k@github さんです。