DockerコンテナをElasticBeanstalkにデプロイする

# 導入
「うちでもDocker使ってみるかぁ」
皆さんの職場で1度は持ち上がった話でしょう。

ここで重要なのは、「気軽に」かつ「実際に」使ってみたいという点です。

通常業務もあるなかで新しい技術を取り入れるには、障壁の低さは必須です。
それと同様に、チュートリアルを超えて、実際にアプリをデプロイできないと、評価のしようがありません。

この悩ましい要求を両立させるソリューションの1つである、Amazon Elastic Beanstalk with Dockerの紹介をします。

# Amazon Elastic Beanstalk with Dockerとは
Amazon Elastic Beanstalkは数あるAmazon Web Serviceの1つで、アプリを動かすために必要なAWSの構築を簡単に行ってくれるサービスです。
ELB、EC2、RDS、DynamoDBなどなど、複数のAWSをブラウザからの操作のみで一気に構築することができます。
事前にアプリを用意さえすれば、AWSの知識が無くてもProductionレベルの環境を構築可能です。
もちろん、コマンドラインからの構築・デプロイや、ファイルでの詳細な設定も可能です。
オートスケールや監視設定も簡単に行えます。

このElastic Beanstalkは、RubyやPHPなどメジャーな言語にはひと通り対応していますが、実はDockerコンテナのデプロイにも対応しているのです。

つまり、ProductionレベルのAWSインフラに、Elastic Beanstalkの簡単さでアプリをデプロイすることが可能なのです。

# 構成
構成は下図のとおりです。
![スクリーンショット 2014-12-05 1.55.42.png](https://qiita-image-store.s3.amazonaws.com/0/11737/43a3975c-5e25-f7df-f3fe-ccfee405ecb2.png)

1. あらかじめリポジトリにアプリをpushしておく
2. アプリのpushに連動してdocker buildがDockerHub上で実行される
3. Elastic Beanstalkを操作して、アプリケーションの環境を作成する
4. Elastic BeanstalkがS3のDockerHub認証ファイルを参照して、DockerHubプライベートリポジトリから最新のアプリ入りコンテナをEC2にデプロイする

操作は、簡単なブラウザ操作で完結する上、日本語での公式ドキュメントもあります。
以下では、あまり明確には書かれていない、つまづきポイントを重点的に説明します。

# 下準備
まずは、Elasstic BeanstalkがDockerHubのPrivate Repoからコンテナをダウンロードできるように、認証を設定します。
DockerHubのPrivateリポジトリを使わないのであれば、この章の設定は不要です。

DockerHubでアカウントを作成した後、作業用PCでdocker loginします。
```
docker login
```
すると、 ホームディレクトリに
```
~/.dockercfg
```
というファイルが生成されます。中身は、以下のとおりです。
```
➜  sampleapp  cat ~/.dockercfg
{"https://index.docker.io/v1/":{"auth":"abcdefg12345678","email":"hoge@fuga.com"}}
```
このファイルを、S3のバケットにアップロードします。
![20140814005924.png](https://qiita-image-store.s3.amazonaws.com/0/11737/e3234798-f293-3b61-b022-33c524d67271.png)
※書いてて気づいたのですが、このファイルは、他人にバレてはいけませんね...何か工夫が必要だな...

これで、Elastic Beanstalkがデプロイ時にDockerHubのPrivateリポジトリを参照することができます。

最後に、Elastic BeanstalkにIAMロールの設定を行います。先ほどのS3バケットを見るため、Read権限が必要です。
詳細は[こちら](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/AWSHowTo.iam.roles.aeb.html)を参照してください。
# 構築
RailsやAmon2など、なんでも良いのでアプリを作っておきます。
また、Dockerrun.aws.jsonという名前のファイルを作っておきます。

```json
{
    "AWSEBDockerrunVersion": "1",
    "Authentication": {
        "Bucket": "sampleapp-bucket",
        "Key": "docker/mydockercfg"
    },
    "Image" : {
        "Name" : "saisa6153/sampleapp:latest",
        "Update": "true"
    },
    "Ports" : [{ "ContainerPort": "80" }]
}
```

今回はこのファイルをElastic Beanstalkの画面からアップロードして、構築を実行させます。
Dockerrun.aws.jsonはzip形式に圧縮しておく必要があります。
手順は、[こちら](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_docker.html)のドキュメントに書いてあるので、適宜参照してください。

次に、Dockerfileを作成します。
今回は、buildの高速化のため、共通部分となるベースイメージと、毎回異なるソースコードが入りうるアプリケーションイメージの2つに分ける戦略を取りました。
もちろん、1つのイメージで完結しても問題ありません。

作成したDockerfileは、アプリケーションに同梱してリポジトリにpushしておきましょう。

その後、再びDockerHubにログインし、DockerHubリポジトリを作成しますが、この時に「Automated Build」にチェックを入れて、ビルドブランチ(master)とDockerfileファイルの位置を指定してください。
Automated Buildを設定することにより、アプリケーションの変更がpushされたタイミングで、毎回Dockerのbuildも走ってくれるようになります。

以下に、サンプルアプリとそのDockerHubリポジトリをおいておきます。適宜参考にしてください。

* [GitHubリポジトリ](https://github.com/saisa6153/DockerSampleApp)
* [DocekrHubリポジトリ(ベースになるイメージ)](https://registry.hub.docker.com/u/saisa6153/sampleapp/dockerfile/)
* [DockerHubリポジトリ(アプリケーションイメージ)](https://registry.hub.docker.com/u/saisa6153/sampleapp-base/dockerfile/)

# 最後に
最近はKubernetesやAmazon EC2 Container Serviceなど、Dockerの運用周りが一段と熱くなってきています。
Elastic Beanstalkはいち早くDockerのデプロイを簡略化した、優秀なサービスだと思います。
実運用段階に入っているDockerを、あなたも使ってみましょう!

# 参考URL
http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-aws-elastic-beanstalk
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html
http://blog.yuukigoodman.net/entry/2014/08/14/012209 の下半分
https://speakerdeck.com/saisa6153/perl-as-a-service