AWS ECRにdockerイメージを登録する

## 概要
AWS Batchで使用するためのdockerイメージを、AWS ECRに登録する手順です。

## 関連記事
- [AWS BatchをCloudformationで作ってみた](https://qiita.com/Esfahan/items/8774afff63ee98b05309)

## Dockerのインストール
こちらの記事を参考に、Dockerを実行する環境を用意してください。
[docker(docker-engine), docker-composeのインストール](https://qiita.com/Esfahan/items/aa5802548ee42d8a98de)

## docker imageの作成
### Dockerfileの作成
サンプルとして、以下のようなpythonの実行環境を構築するDockerfileを作成します。

```bash:Dockerfile
FROM centos:centos7

# Install dependencies
RUN yum -y update
RUN yum -y install \
            git \
            zlib \
            tk-devel \
            tcl-devel \
            ncurses-devel \
            gdbm-devel \
            db4-devel \
            readline-devel \
            zlib-devel \
            bzip2-devel \
            sqlite-devel \
            openssl-devel \
            libXext.x86_64 \
            libSM.x86_64 \
            libXrender.x86_64 \
            gcc \
            gcc-c++ \
            libffi-devel \
            python-devel \
            patch \
            bzip2 \
            make

ENV ROOT_PATH /root

# Download Python3.5.2
WORKDIR $ROOT_PATH
RUN curl -O https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz
RUN tar xzvf Python-3.6.2.tgz

# Install Python3.5.2
WORKDIR $ROOT_PATH/Python-3.6.2
RUN ./configure --with-threads
RUN make install

# Install pip
WORKDIR $ROOT_PATH
RUN curl -O https://bootstrap.pypa.io/get-pip.py
RUN python get-pip.py

# Init script
ADD init.sh /usr/local/
ADD main.py /usr/local/

WORKDIR /root
CMD ["/bin/bash"]
```

### 実行するシェルスクリプトの作成
Dockerfileで実行するinit.shを作成します。

```bash:init.sh
echo 'Batch is running...'
python /usr/local/main.py
echo 'Batch is done'
```

### バッチ処理の作成
c4 familyで実行する、負荷のかかるプログラムを作ります。
こちらのプログラムを拝借します。
参考：[Pythonで素数列挙と素数判定](https://qiita.com/neko_the_shadow/items/4ebad619564a48f5a97f)

```py:main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import math

# 整数xが素数かどうかを判定する
def is_prime(x):
    if x < 2: return False # 2未満に素数はない
    if x == 2 or x == 3 or x == 5: return True # 2,3,5は素数
    if x % 2 == 0 or x % 3 == 0 or x % 5 == 0: return False # 2,3,5の倍数は合成数

    # ためし割り: 疑似素数(2でも3でも5でも割り切れない数字)で次々に割っていく
    prime = 7
    step = 4
    while prime <= math.sqrt(x):
        if x % prime == 0: return False

        prime += step
        step = 6 - step

    return True

if __name__ == '__main__':
    ls = [x for x in range(1000000) if is_prime(x)]
```

## docker imageの作成
前述の項で作成したDockerfileを使って、docker imageを作成をします。

```
$ docker build -t sample-aws-batch:latest .
```

imageが作成されたことを確認します。

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample-aws-batch    latest              50d748c4627a        25 seconds ago      874MB
centos              centos7             d123f4e55e12        9 days ago          197MB
```

コンテナを起動して、Exitしないことを確認ます。

```
$ docker run --rm -itd sample-aws-batch
d0fe3f2cfda8e15fec4ff508c3bb504132a8cb711a0358476ca2c2055e0f5a10

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
d0fe3f2cfda8        sample-aws-batch    "/bin/bash"         4 seconds ago       Up 3 seconds                            determined_wozniak
```


## AWS ECRにdocker imageを登録
作成したdocker imageをAWS ECRに登録します。

### ECRにレポジトリを作成
以下のコマンドでECRにレポジトリを作成します。

```
$ aws ecr create-repository --repository-name sample-aws-batch-repo

{
    "repository": {
        "createdAt": 1510565002.0,
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:xxxxxxxxxxxx:repository/sample-aws-batch-repo",
        "registryId": "xxxxxxxxxxxx",
        "repositoryName": "sample-aws-batch-repo",
        "repositoryUri": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-aws-batch-repo"
    }
}
```

レポジトリを作成したら、以下の手順でdocker imageをpushします。

### ECRにログイン
以下のコマンドを実行すると、ログインするための長いコマンドが表示されるので、そちらをコピペして実行します。

```
$ aws ecr get-login --no-include-email --region ap-northeast-1
docker login　・・・・・・・・・
```

長いコマンドが表示されるのでコピペして実行するのですが、以下のようにファイルに書き出して実行したほうが楽です。

```
$ aws ecr get-login --no-include-email --region ap-northeast-1 > login.sh
$ bash login.sh
```

表示されたコマンドを実行して、`Login Succeeded`と出力されたら、ログイン成功です。

```
$ docker login -u AWS -p <出力された値> https://xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
``` 

作成したdocker imageに、以下のようにしてtagを付けます。
repositoryUriの後ろにlatestと付けます。

```
$ docker tag sample-aws-batch:latest \
    xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-aws-batch-repo:latest
```

### ECRにimageをPUSH
ECRにpushします。 

```
$ docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-aws-batch-repo:latest
```

AWS Consoleで、ECRにdocker imageが登録されているか確認してください。


以上で完了です。

続けて、[AWS Batchの構築](https://qiita.com/Esfahan/items/8774afff63ee98b05309)をします。

## 参考
- [AWS Batchを使って5分以上かかる処理を実行してみる](https://dev.classmethod.jp/cloud/aws-batch-5min-over/)