Docker イメージの働き

以下のサイトがオリジナルであり、実際に実行しながら試した際のメモである。
http://docs.docker.com/userguide/dockerimages/

これまでは Docker のイメージを Docker ホストにダウンロードする方法であったが、もし対象となるイメージがホストに存在していなければ、レジストリからダウンロードする。(デフォルトのレジストリは、Docker Hub の公開レポジトリ)

# 1. ホスト上のイメージの一覧
ローカルホスト上で持っているイメージの一覧を `docker images` コマンドを利用して取得する。

```bash:images
$ docker images
REPOSITORY         TAG               IMAGE ID            CREATED            VIRTUAL SIZE
ubuntu              14.04              63e3c10217b8        5 days ago          188.3 MB
training/webapp     latest              02a8815912ca        12 weeks ago        348.7 MB
```

どのリポジトリからのものか（ubuntuなど）、各々のイメージのタグ（14.04など）イメージのイメージ IDを確認できる。
リポジトリは複数の種類のイメージを持っている可能性がある。ubuntu イメージの場合は、Ubuntu 10.04, 12.03, 12.10, 13.04, 13.10, 14.04 のように、複数のバージョンを扱っており、各々のイメージはタグで識別することができる。コンテナを実行しようとするとき、タグ付けされたイメージを指定するには、次のようにする。

```bash:run
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
```
注）イメージのどのようなバージョンが使われているか、常に厳密に分かるようになるため、常に特定のタグを付けたイメージの使用が推奨されている。（例えば ubuntu:12.04）。

# 2. 新しいイメージの取得
Docker は、Docker ホスト上に存在しないあらゆるイメージを、自動的にダウンロードする。しかし、場合によってはコンテナを起動するのに少し時間がかかってしまう場合がある。もし、予めイメージの事前読み込みをしたい場合は、 `docker pull` コマンドを使って事前ダウンロードをすることが可能である。

イメージが手元にないときに実行すると1分9秒かかる

```bash:time
$ time docker run centos /bin/echo "hello world"
Unable to find image 'centos:latest' locally
Repository centos already being pulled by another client. Waiting.
hello world
real    1m9.738s
user    0m0.013s
sys     0m0.027s
```

docker pullで事前にcentosのイメージをダウンロードしてから実行すると1.7秒ですむ。

```bash:pull
$ docker pull centos
latest: Pulling from centos
f1b10cd84249: Pull complete
c852f6d61e65: Pull complete
7322fbe74aa5: Already exists
centos:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:57554136c655abb33ecb7bb790b1db0279668d3763c3b81f31bc6c4e60e4a1f3
Status: Downloaded newer image for centos:latest
```

```bash:time
$ time docker run centos /bin/echo "hello world"
hello world
real    0m1.737s
user    0m0.016s
sys     0m0.020s
```

なおdocker rmiコマンドでイメージの削除を行うことができる。消そうとしている対象のイメージを使ったコンテナが起動しているときは、そのコンテナを停止してからでないとイメージを削除することはできない。

注）
Proxy環境下でイメージを取得できないときは、下記サイトに記載されているように `/usr/lib/systemd/system/docker.serviceにEnvironment="HTTP_PROXY=http://{proxy_server}:{port}"` を追記する。
http://qiita.com/RyotaIshii/items/44061e35966c11296d64

# 3. イメージの検索
Docker の特長の１つに、沢山の人が作成した様々な Docker イメージがあり、大部分は Docker Hub にアップロードされている。これらのイメージは Docker Hub のウェブサイトから、または `docker search` コマンドを使って、コマンドラインからイメージを検索することが可能である。

例えば、欲しいイメージが、ウェブアプリケーション開発のために Ruby と Sinatra がインストールされているものとする。イメージを `docker search` コマンドを使って sinatra という言葉を含むイメージを探すことができる。

```bash:search
$ docker search sinatra
NAME                                   DESCRIPTION                       STARS     OFFICIAL   AUTOMATED
tdiary/rpaproxy-sinatra                                                  1                    [OK]
gwjjeff/sinatra                                                          0                    [OK]
・・・
rikap/ruby-sinatra                    Docker for hosting Sinatra apps   0                    [OK]
```

実行すると sinatora という言葉を含む沢山のイメージの情報が表示される。表示されるのは、NAME(イメージ名)、DESCRIPTION(説明)、STAR(スター数)（イメージがソーシャル上で有名である指標 - 利用者がイメージが好きなら "star" することができます）、そして、OFFICIAL (公式かどうか)、AUTOMATED(自動ビルド)の状態。公式レポジトリとは、Stackbrew プロジェクトによって構築と監視されたもので、自動ビルドされた自動化されたレポジトリにあり、これによって、出所(source)とイメージの中身の安全性を確認する。

適切なイメージを見つけたら `docker pull` でイメージをダウンロードし、 `docker run` でコンテナを起動する。

# 4. カスタムイメージの作成
#### 4.1. コミットしたイメージの更新
イメージを更新するためには、まず、更新したいイメージからコンテナを作成。

```bash:run
$ docker run -t -i centos /bin/bash
[root@e2ef0584c314 /]#
```

デフォルトではrubyはインストールされてないので、rubyをインストール

```bash:ruby
[root@e2ef0584c314 /]# which ruby
/usr/bin/which: no ruby in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
[root@e2ef0584c314 /]# yum install –y ruby
```

作業が終わったら、 `exit` コマンドを実行してコンテナから抜ける。 `docker commit` コマンドを対象のイメージに使う事で、このコンテナのコピーにコミットすることができる。 `m` フラグは、バージョンコントロールシステムにコミットするような、コミットメッセージを明示し、 `-a` フラグは、更新に当たっての作者を指定する。

```bash:commit
$ docker commit -m "add ruby" -a="Tadayasu Yotsu" e2ef0584c314 yotsu/centos:v2
057cb8323f885bb6d97fe27c01df53fa16adcb214b075b65987c85637e7f73eb
```

`docker images` コマンドでコミットした新しいイメージを確認

```bash:images
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
yotsu/centos        v2                  057cb8323f88        56 seconds ago      253.9 MB
ubuntu              14.04               63e3c10217b8        6 days ago          188.3 MB
centos              latest              7322fbe74aa5        7 weeks ago         172.2 MB
training/webapp     latest              02a8815912ca        12 weeks ago        348.7 MB
```

新しく作成したイメージを元にコンテナを使うには、次のようにする。

```bash:run
$ docker run -t -i yotsu/centos:v2 /bin/bash
[root@d9f03df79e61 /]#
```

#### 4.2. Dockerfile からイメージを作成する
`docker commit` コマンドを使うことは、イメージを拡張するための簡単な方法だが、少々煩わしく、チーム間でイメージを開発プロセスにおいて共有するのは簡単ではない。スクラッチで（ゼロから）新しいイメージを作る代わりに、 `docker build` というコマンドを使う。
実行する為には Dockerfile を作成し、Docker に対してどのようにイメージを構築するかの命令セットを記述していく。

ディレクトリを作成し、Dockerfile を配置。

```bash:dockerfile
$ mkdir images
$ cd images/
$ vi Dockerfile
```

```docker:Dockerfile
FROM ubuntu:14.04 # ソースとなるイメージを伝える。この場合,ubuntu 14.04 イメージの上の新規イメージを基盤とする事を伝える。
MAINTAINER Tadayasu Yotsu　# 誰が新しいイメージを管理するのか明示
ENV http_proxy http://{proxy_server}:{port}　# 環境変数設定。
RUN apt-get -qq ruby　# イメージの中で実行するコマンド。
```

Dockerfile を使って、 `docker build` コマンドによりイメージを構築。
-t フラグで新しく yotsuに所属するイメージを作成し、ubuntu という名前のレポジトリで、v2 というタグを使用
．はカレントディクトリにあるdockerfileを使うことを意味

```bash:build
$ docker build -t="yotsu/ubuntu:v2" .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
 ---> 63e3c10217b8
Step 1 : MAINTAINER Tadayasu Yotsu
 ---> Using cache
 ---> fefb71c83805
Step 2 : ENV http_proxy http://{proxy_server}:{port}
 ---> Running in 3f38a47c6e57
・・・
Removing intermediate container 3261d0c6cc1f
Successfully built d520101b1b89
```

構築のコンテキスト（環境）をアップロードし、Dockerfile内の指示を段階的に実行する。
新しいコンテナを構築する各々のステップに於いて、コンテナの中に対して命令を出し、 `docker commit` ワークフローのようにコンテナに対する変更をコミットする。全ての命令が d520101b1b89 というイメージに対して実行され、中間コンテナは削除される。
これで、私たちは私たちの新規イメージからコンテナを起動できます。

```bash:run
$ sudo docker run -t -i yotsu/ubuntu:v2 /bin/bash
root@8196968dac35:/#
```

# 5. イメージにタグを付ける
`docker tag` コマンドを使うことにより、コミットやビルド後でも、既存イメージに対するタグを追加することができる。そのためには `docker tag` コマンド( `docker tag  IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]` )を使う。

```bash:tag
$ docker tag 057cb8323f88 yotsu/test1:dev
```

# 6. Docker Hub にイメージを送る(push)
`docker push` コマンドにより、docker hubにイメージを送ることができる。

```bash:push
$ docker push yotsu/test1:dev
```