Docker 入門　Dockerfileを使用したイメージ作成・Docker Hubへのプッシュ

前回使用したクジラが言葉を話すイメージをし
Dockerfileを作成、イメージを構築し、Docker Hubにプッシュしていきます。

前回：Docker 入門　Dockerの説明からhello-worldまで
https://qiita.com/mtakehara21/items/44282271d07e1f623cea

## Dockerfileを作成
Dockerfile　＝　イメージの定義ファイル
作業ディレクトリにDockerfileを作成し、コマンドを記載していきます。

``` Dockerfile
// FROMにて新しいイメージ構築にあたり元となるイメージを指定する
// 元のイメージのレイヤの上に新しいイメージのレイヤを重ねることによりカスタマイズする。
FROM docker/whalesay:latest

// RUN = イメージビルドの際に実行する命令
// apt-get -y update = パッケージリストの更新
// apt-get install -y fortunes = forrunesパッケージをインストール
RUN apt-get -y update && apt-get install -y fortunes

// CMD コンテナ作成後に実行するコマンドを指定する命令
// fortuneで格言を生成し、cowsayでクジラに喋らせる
CMD /usr/games/fortune | cowsay
```
*Ubuntuのためapt-get

## Image buildを実行する
Image build　＝　Dockerfileからイメージを構築すること

``` terminal
// build: イメージをビルドするサブコマンド
// -t: 作成したイメージに名前をつけるコマンド
// .: ビルドコンテキスト。イメージ作成時にアクセスできるディレクトリファイルの範囲を示すもの。
// .(ピリオド)はカレントディレクトリ

docker build -t docker-whale .
```

ビルドされるときに、ビルドコンテキストにあるファイルはすべてにDocker daemonに送られる
そのため、重いファイルが重いファイルが存在するときは処理が重くなる。
しかし、イメージが作られるわけではなく、ただ送られるだけ。


### Q.特に指定してないけどどのドッカーファイルが読み込まれるの？
ビルドコンテキストのDockerfileが読み込まれる。
つまり、ビルドコンテキストがカレントディレクトリならば、カレントディレクトリのDockerfileが読み込まれる。


### ビルド結果

```
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM docker/whalesay:latest
 ---> 6b362a9f73eb
Step 2/3 : RUN apt-get -y update && apt-get install -y  fortunes
 ---> Running in 3b59d341885c
Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
Get:2 http://archive.ubuntu.com trusty-security InRelease [65.9 kB]
Hit http://archive.ubuntu.com trusty Release.gpg
Get:3 http://archive.ubuntu.com trusty-updates/main Sources [521 kB]

--- 大幅に省略　ーーー

Removing intermediate container 3b59d341885c
 ---> 2507f55aac83
Step 3/3 : CMD /usr/games/fortune | coway
 ---> Running in 476917e7c501
Removing intermediate container 476917e7c501
 ---> fdee5ab43344
Successfully built fdee5ab43344
Successfully tagged docker-whalesay:latest
```

`Sending build context to Docker daemon  2.048kB` 
ビルドコンテキストのファイルをDocker deamonへ転送している

###ビルドのプロセス 
FROM / RUN / CMDの３ステップ

#### FROM 
イメージの取得を行う。ローカルにある場合はそれを使用。

#### RUN 
イメージから一時的なコンテナを起動し、RUN命令
終了したら一つのレイヤーとして保存する。

#### CMD 
RUNまでで作成されたイメージからコンテナワオ一時的に起動する。
コマンド命令のコマンドコンテナ内をセットアップ
終了後保存する。

上記３ステップで作成されたものを名前をつけて保存する。
`tagged docker-whalesay:latest`


###イメージが作成されたか確認する

```
$docker images 

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker-whale     latest              fdee5ab43344        5 minutes ago       277MB
hello-world         latest              4ab4c602aa5e        3 weeks ago         1.84kB
docker/whalesay     latest              6b362a9f73eb        3 years ago         247MB
```

###ビルドキャッシュ
再度ビルドを実行すると、キャッシュが使用され、Using cacheと表示されコマンドが実行されない。

```
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM docker/whalesay:latest
 ---> 6b362a9f73eb
Step 2/3 : RUN apt-get -y update && apt-get install -y  fortunes
 ---> Using cache
 ---> 2507f55aac83
Step 3/3 : CMD /usr/games/fortune | cowsay
 ---> Running in 7fdaa0cc35f0
Removing intermediate container 7fdaa0cc35f0
 ---> 4846874659df
Successfully built 4846874659df
Successfully tagged docker-whale:latest

```

実行させたい場合は`--no-cache`を宣言する

```
$docker build --no-cache -t docker-whale .
```


## Docker HubにPushしてみる

###DockerにおけるPush 
リポジトリにイメージを追加すること

###Docker Hubにログイン
ターミナルからPushする場合はDocker Hubへのログインが必要である。

```
// レジストリサーバーへログインするコマンド
$docker login

// Quay.ioレジストリにログインする場合
$docker login quay.io
```
様々なレジストリが存在しているが、デフォルトで`docker.io`



###リポジトリの作成
Docker Hubにいき、リポジトリを作成します。
https://hub.docker.com/

<img width="1439" alt="スクリーンショット 2018-09-30 18.24.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/253092/958bd4e2-c3fb-e3ce-639c-a29602eb3117.png">

* リポジトリ名
* 簡単な説明
* 説明
* 公開範囲(Public or Private)
を設定します

説明等は後から追加することができます。
無料ユーザなら一つだけPrivateで作成できるとのこと。


Createを押して作成が完了したらなら
このリポジトリに向けてビルドしたイメージをＰｕｓｈしていきます。

### タグ付け

```
// DockerID/イメージ名：タグ名
$docker tag docker-whale thomas21/docker-whale:ver1
```
タグ名を指定しない場合はデフォルトで`latest`になる


###Docker HubへPush

```
$docker push thomas21/docker-whale:ver1

The push refers to repository [docker.io/thomas21/docker-whale]
a9a887219ec6: Pushed
5f70bf18a086: Mounted from docker/whalesay
d061ee1340ec: Mounted from docker/whalesay
d511ed9e12e1: Mounted from docker/whalesay
091abc5148e4: Mounted from docker/whalesay
b26122d57afa: Pushed
37ee47034d9b: Pushed
528c8710fd95: Pushed
1154ba695078: Pushed
ver1: digest: sha256:a907f3ee5c2be14ea6f96e00a342e8893ad6d857f8fde0fbffb4ae068569f8c4 size: 2614
```

これでPush完了！！

試しにローカルから削除してみる

```
$docker rmi -f 4846874659df
Untagged: docker-whale:latest
Untagged: thomas21/docker-whale:ver1
Untagged: thomas21/docker-whale@sha256:a907f3ee5c2be14ea6f96e00a342e8893ad6d857f8fde0fbffb4ae068569f8c4
Deleted: sha256:4846874659dfbf4e957c4534fe1901ec04c1032ece708c2a1171029c49748b51
```

そして、pullを実行！

```
 docker pull thomas21/docker-whale:ver1
ver1: Pulling from thomas21/docker-whale
188ab0d3421d: Already exists
079c8ca7aeb2: Already exists
278f7f06ff44: Already exists
a3ed95caeb02: Already exists
b6675f4fe3bd: Already exists
c57b6bcc83e3: Already exists
8978f6879e2f: Already exists
8eed3712d2cf: Already exists
83b2047c4766: Already exists
Digest: sha256:a907f3ee5c2be14ea6f96e00a342e8893ad6d857f8fde0fbffb4ae068569f8c4
Status: Downloaded newer image for thomas21/docker-whale:ver1
```

新しくダウンロードされているのがわかります！！
実行してみると、前回作成したクジラが出現し、名言を吐いています！

```
docker run thomas21/docker-whale:ver1
 _________________________________________
< On the eighth day, God created FORTRAN. >
 -----------------------------------------
    \
     \
      \
                    ##        .
              ## ## ##       ==
           ## ## ## ##      ===
       /""""""""""""""""___/ ===
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
       \______ o          __/
        \    \        __/
          \____\______/
```

これで実際に公開することができました！！！
いえーい！！！


## 参考
ゼロからはじめる Dockerによるアプリケーション実行環境構築
セッション4 chapter17~20
https://www.udemy.com/docker-k/