LoginSignup
23
22

More than 5 years have passed since last update.

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

Posted at

この記事は 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 さんです。

 

23
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
22