ECSでrailsアプリケーション（開発環境)を動かしてみる。


最近、テストサイトを社内向けに公開する機会があり、ElasticBeanstalkを使おうと思ったのですが、意外とGemfileのPrivateなリポジトリのアクセスに手間取り（結局、途中で諦め）、こんな時間がかかるならはやりのDockerを使ってRailsを公開してみようと思い立ったのが今回です。

（現在稼働中のものを元に書いたので少し抜けがあるかもしれません。）


今回紹介すること
---

* 今回使ったDockerfile
	* rails
	* nginx
* ECSの設定



注意
---

今回は、あくまでも社内限定のため ***開発環境*** のためいろいろとガバガバな部分があると思います。ECSでrailsを動かすことを目標としてます。

また、今回Dockerを触ったのが始めてたので少し設定ファイルに間違いがあるかもしれません。


rails環境に使ったDockerfileの設定
---

~~~
## amazonlinuxのイメージを落としてくる。
FROM amazonlinux:latest
MAINTAINER RyujiKawazoe

## システムの更新
RUN yum -y update

## rubyに必要なもの
RUN echo "install ruby environment"
RUN yum install -y git vim sudo tar wget
RUN yum install -y gcc make gcc-c++ zlib-devel httpd-devel openssl-devel curl-devel sqlite-devel

## rbenvを使わずに、ruby2.3を落とす。
RUN echo "install ruby2.3"
RUN cd /root/ && wget http://cache.ruby-lang.org/pub/ruby/ruby-2.3.3.tar.gz
RUN cd /root/ && tar zxvf ruby-2.3.3.tar.gz
RUN cd /root/ruby-2.3.3 && ./configure && make && make install
RUN gem install bundler --no-ri --no-rdoc -V
RUN gem install rb-readline --no-ri --no-rdoc -V

##pip インストール準備。
RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python
RUN pip install awscli

## aws 連携準備
RUN yum install -y expect

## ssh認証をコピーする（秘密鍵を元に公開鍵を作る。codecommitの認証のため、ssh/configファイルを作成する
## ssh/configには、codecommit連携の他にssh接続先確認をoffにする宣言もしておく。
RUN mkdir -p /root/.ssh
ADD [CodeCommitとの認証が取れている秘密鍵] /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa
RUN ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
RUN chmod 644 ~/.ssh/id_rsa.pub
ADD [codecommitとのssh認証をかけるための設定が描かれているconfigファイル] /root/.ssh/config

## railsプロジェクトのダウンロード
RUN mkdir /app
## キャッシュされたら困るので。（少しここは、改善したほうがいい？）
ADD dummyfile /data/
RUN git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/hogehogehoge /app/project
RUN cd /app/project && git pull origin master
RUN cd /app/project && bundle install

## rails アプリケーションの起動
EXPOSE 3000
WORKDIR /app/project
ENTRYPOINT ["puma"]

~~~


ところどころに不必要なものもあるかもしれないが、やっていることは以下

1. amazonlinuxイメージを持ってくる
2. ruby(rails）を動かすパッケージを入れる
3. codecommitにソースがあるので（プロジェクト本体、Gemfileに記載されているライブラリ)、codecommitに内部からアクセスするための設定を入れる
	* ここに関してはやり方が正解かどうか悩ましい
	* codecommitとの連携は、[クラスメソッドさんの記事](http://dev.classmethod.jp/cloud/aws/using-codecommit-git-repository/)とか参照
4. gemたちを落としてきて、pumaを起動する。


これで、ECS上で起動させる ***rails*** を動かすDockerイメージができました。

お次は、nginxの設定ファイルです。

nginx環境に使ったDockerfileの設定
---

* Dockerfile

```
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
```

* nginx.conf


```
http {
    upstream puma {
      server app:3000;
    }

    server {
        listen       80;

        location / {
            proxy_pass http://puma;
        }
    }
}

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

```

`app:3000` とか何だ？と思う方がいるかもしれませんが、コンテナどうしのリンクとかいうやつです。

以下の記事を参考にさせていただきました。

* http://qiita.com/7kaji/items/e4ad05188df6d05aff97
* http://qiita.com/Arturias/items/75828479c1f9eb8d43fa

ECSの設定について
---

大まかな流れとしては以下です。

1. 今回作った２つのDockerイメージをプッシュするリポジトリを作る。
2. タスク定義を行う

Dockerイメージをプッシュするリポジトリを作る
---

![スクリーンショット 2017-01-26 10.35.38.png](https://qiita-image-store.s3.amazonaws.com/0/18331/a5c59e84-dbbf-b4db-ca53-590c02ab4aee.png "スクリーンショット 2017-01-26 10.35.38.png")

ここですね。特に難しいことはないので、詳しい手順は書きません。

今回２つDockerイメージを作ったので、２つ用意してください。


ECSのタスク定義
---

![スクリーンショット 2017-01-26 10.39.24.png](https://qiita-image-store.s3.amazonaws.com/0/18331/a74ce18b-9cdc-ee5e-7b1d-f0ec7c86a5c5.png "スクリーンショット 2017-01-26 10.39.24.png")

|設定|内容|
| --- | --- |
| タスク定義名 | 適当 |
| タスクロール | もしかしたら、他のサービスと連携する可能性があるかもしれないので、専用のIAMRoleを作っておきました。
| ネットワークモード | host or bridge接続があったのですが、bridge接続でいいのかな？ https://www.agilegroup.co.jp/technote/docker-network-in-bridge.html |

![スクリーンショット 2017-01-26 10.45.35.png](https://qiita-image-store.s3.amazonaws.com/0/18331/293978b3-de20-5df8-3f73-e7d182bb4534.png "スクリーンショット 2017-01-26 10.45.35.png")

そして、今回作ったDockerイメージを登録。

まずはrailsを動かすコンテナの設定

![スクリーンショット 2017-01-26 10.47.56.png](https://qiita-image-store.s3.amazonaws.com/0/18331/442d9cb5-3bdc-6370-75a5-0eb54b06d45e.png "スクリーンショット 2017-01-26 10.47.56.png")

| 設定 | 内容 |
| --- | --- |
| コンテナ名 | puma あとで、nginxのコンテナとリンクするために、分かりやすい名前で |
| イメージ | 先ほど作ったrailsイメージリポジトリののURIを |
| メモリ制限 | 300MBおすすめとか書いてあるので、とりあえず300MBで |
| CPUユニット数 | 1でいいか（適当) |

上の設定以外は特に、内容はデフォルトのままです。
Dockerのリンク機能を使うため、ポートマッピングはしてません。

続いてnginxコンテナのイメージを追加します。

| 設定 | 内容 |
| --- | --- |
| コンテナ名 | nginx |
| イメージ | 先ほど作ったnginxイメージリポジトリののURIを |
| メモリ制限 | 300MBおすすめとか書いてあるので、とりあえず300MBで |
| CPUユニット数 | 1でいいか（適当) |
| ポートマッピング | ホスト80, コンテナ80 |
| リンク | puma:app |


nginxコンテナのポートマッピング設定


![スクリーンショット 2017-01-26 10.55.05.png](https://qiita-image-store.s3.amazonaws.com/0/18331/f456452a-5011-b652-ac0f-4f87e594a10f.png "スクリーンショット 2017-01-26 10.55.05.png")

nginxコンテナのリンク設定

![スクリーンショット 2017-01-26 10.57.58.png](https://qiita-image-store.s3.amazonaws.com/0/18331/f5e7cd42-fed3-46f1-b4c1-589a9e07614e.png "スクリーンショット 2017-01-26 10.57.58.png")

ここがコンテナ間でのリンクとなります。
`puma`に関しては、railsコンテナで指定した名前appに関してはnginx.confの設定で使った名前を使っています。


クラスターの作成
---

![スクリーンショット 2017-01-26 11.02.20.png](https://qiita-image-store.s3.amazonaws.com/0/18331/fa448a88-23b7-7fb6-d9f8-3175da5e3bc1.png "スクリーンショット 2017-01-26 11.02.20.png")

これですね。
必要に応じてVPC、IAM、セキュリティーグループの設定を行ってください。

ただ、EC2に割り当てるIAMには「AmazonEC2ContainerServiceforEC2Role」ポリシーが必要です。


サービスの設定
---


![スクリーンショット 2017-01-26 11.06.11.png](https://qiita-image-store.s3.amazonaws.com/0/18331/909e36b6-06b2-e8a6-a8da-2f8373e1e876.png "スクリーンショット 2017-01-26 11.06.11.png")

| 設定 | 内容 |
| --- | --- |
| タスク定義 | 先ほど作ったタスクを設定してください |
| クラスター | 先ほど作ったクラスターを設定してください |
| サービス名 | 適当 | 
| タスクの数 | 1 |
| 最小ヘルス率 | 1 |
| 最大ヘルス率 | 100 |

正直なところ、最小ヘルス率最大ヘルス率に関しては適当すぎます。

詳しい設定の仕方に関しては、以下の記事が参考になるかもしれません。

* http://qiita.com/uchihara/items/8647c94f7af607a9a236#blue-green-deployment
* http://aws.typepad.com/sajp/2015/12/amazon-ecs-launches-new-deployment-capabilities-cloudwatch-metrics-singapore-and-frankfurt-regions.html

これでサービスを登録すれば、railsアプリケーションがみれると思います。



その他
---

* ssh接続確認をoffにするやり方
	* http://qiita.com/shotaTsuge/items/48bdaccdafa5475d9016