Amazon EC2 Container Registry (ECR)を使ったデプロイフローの検証（未完）

# 序文

PHPで作ったwebアプリケーションの本番環境をとある事情でDockerで運用しています。前々から個人用のDockerHubにImage置けたらpullしてrunするだけでデプロイ楽なのにと思っていましたが、[Amazon EC2 Container Registry (ECR)](https://aws.amazon.com/jp/ecr/?nc2=h_m1)なるものがあるらしく、こいつを使っていい感じのデプロイフローが出来ないか試してみました。

Google Cloud Platform派の方は[こちら](https://cloud.google.com/container-registry/)をどうぞ。

_ちなみに前提として今回のデプロイ先はAmazon EC2 Container ServiceではなくCentOS6系の上に建てたDockerです。_

# 今回試したいこと

1. [開発環境でbuildしてからECRにpushしてみる](http://qiita.com/fknsy/items/c002bb329d4e091eb8b3#開発環境でbuildしてからecrにpushしてみる)
1. [ステージング環境でpullして、runしてみる](http://qiita.com/fknsy/items/c002bb329d4e091eb8b3#ステージング環境でpullしてrunしてみる)
1. [Jenkinsを使ってDocker imageをbuildしてpush出来るようにする](http://qiita.com/fknsy/items/c002bb329d4e091eb8b3#jenkinsを使ってdocker-imageをbuildしてpush出来るようにする)
1. [Jenkinsを使ってステージング環境でpullしてrun出来るようにする](http://qiita.com/fknsy/items/c002bb329d4e091eb8b3#jenkinsを使ってステージング環境でpullしてrun出来るようにする)

# 開発環境でbuildしてからECRにpushしてみる

AWSのWebConsoleの`pushコマンドの表示`に書いてある通りにすれば出来ますが、作業ログの役割もあるのでここにも書いておきます。
（WebConsoleの方はrepository名が自分のものになっていてそのままコピペできるようになっているので、作業時はそちらを参考にした方がいいです。AWSさん本当に親切。）

### 0. 前準備

[AWS コマンドラインインターフェイス](https://aws.amazon.com/jp/cli/)が必要です。
そしてAWS コマンドラインインターフェイスを入れるためには[pip](https://pip.pypa.io/)が必要です。
また、Python 2.6.5 以降が必要ですが、流石にこれは気にしなくてもだいたい入っているでしょう。

pip install

~~~bash
curl -kL https://bootstrap.pypa.io/get-pip.py | python
~~~

AWS コマンドラインインターフェイス install

~~~bash
pip install awscli
~~~

アカウント設定

~~~bash
aws configure
~~~

~~~bash
AWS Access Key ID [None]: 自分のを入力して下さい
AWS Secret Access Key [None]: 自分のを入力して下さい
Default region name [None]: ap-northeast-1（東京リージョンならこれ）
Default output format [None]: json（適当に好きな形式を）
~~~

### 1. docker loginコマンドを取得

~~~bash
aws ecr get-login --region ap-northeast-1
~~~

### 2. 前の手順で返されたdocker loginコマンドを実行する

### 3. Docker imageを作成する（すでに作成済みの場合はとばせます）

~~~bash
docker build -t my_image .
~~~

### 4. pushようにタグを付けなおす

~~~bash
docker tag my_image:latest hogehogehoge.dkr.ecr.ap-northeast-1.amazonaws.com/repository_name:latest
~~~

### 5. pushする

~~~bash
docker push hogehogehoge.dkr.ecr.ap-northeast-1.amazonaws.com/repository_name:latest
~~~

# ステージング環境でpullして、runしてみる

push編とやることはだいたい同じです。

### 0. 前準備

AWS コマンドラインインターフェイスが以下ry
pipが以下ry

__ここでもaws configureすることになるので、真面目にやるなら専用のIAM用意してECRのpull権限だけ振るべきだと思います。__

### 1. docker loginコマンドを取得

~~~bash
aws ecr get-login --region ap-northeast-1
~~~

### 2. 前の手順で返されたdocker loginコマンドを実行する

### 3. pullする

~~~bash
docker pull hogehogehoge.dkr.ecr.ap-northeast-1.amazonaws.com/repository_name:latest
~~~

# Jenkinsを使ってDocker imageをbuildしてpush出来るようにする

ごめんなさい。ここから先は実は試せていません。理由は[後述](http://qiita.com/fknsy/items/c002bb329d4e091eb8b3#docker-pull途中でなぜかdockerがdownする)します。
[Amazon ECR](https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR)を使えば簡単にできそう。

# Jenkinsを使ってステージング環境でpullしてrun出来るようにする

[SSH plugin](https://wiki.jenkins-ci.org/display/JENKINS/SSH+plugin)でsshしてpullしてrunするつもりでした。

# 辛かったこと

### `Invalid repository name (namespace/repo), only [a-z0-9-_.] are allowed`でpullできない

> 名前空間はオプションであり、スラッシュを使用してリポジトリ名に含めることができます（namespace/repo など）。

と書いてあったので、そうかそうかと「/」で区切って名前空間を切ったところ、CentOSでpullできない自体に遭遇しました。試しにMac上でpullしてみたら普通に出来たのでバージョン依存の何らかのバグっぽいです。`docker version`したらCentOSは1.7でMacは1.13。だいぶ古かったのでバージョンを上げてみることにしました。

### Docker 1.8からCentOS6はサポート外

(´・ω・`)
詳しくは下記をどうぞ。
[Docker v1.8 から RHEL/CentOS6 はサポート外になった](http://blog.amedama.jp/entry/2015/08/26/213828)

CentOS6系そろそろ辛いですね。

### Docker pull途中でなぜかDockerがdownする

名前空間を使わずに_つなぎでrepositoryを作り直したところpullが開始されました。
しかし、しばらくするとなぜか必ずDockerのdemonが強制終了してしまいます。

logを辿ったところ下記のerrorを発見（ちなみにlogの場所は普通に`/var/log/docker`でした。）

~~~
level=error msg="Error from V2 registry: unable to copy v2 image blob data: read tcp ip_address: i/o timeout"
panic: runtime error: invalid memory address or nil pointer dereference
~~~

原因はこのあたり？
https://github.com/docker/distribution/issues/785