Dockerの基礎をまとめてみた ~ 第三章：Dockerコマンド - image編

# 第三章 : Dockerコマンド - image編
本章では、Dockerコマンドの `image` について記載します。

## イメージ操作
イメージの操作は、 `docker image` コマンドを使います。 `docker image` で利用できるコマンドは以下の通りです。

|コマンド|概要|
|:--:|:--|
|build|Dockerfileからイメージを作成する|
|history|イメージの履歴を表示する|
|import|tarに圧縮されたファイルシステムからイメージを作成する<br>※ **load** との違いは後述|
|inspect|イメージ情報を表示する|
|load|tarや標準入力からイメージを読み込む<br>※ **import** との違いは後述|
|ls|イメージのリストを表示する|
|prune|使用されていないイメージを削除する|
|pull|リポジトリからイメージをダウンロードする|
|push|リポジトリにイメージを登録する|
|rm|ローカルにあるイメージを削除する|
|save|イメージからtarを作成する|
|tag|元のタグから新しいタグを作成する|

### build コマンド
コマンド例は、 `docker image build [OPTIONS] PATH | URL | -` です。OPTIONSは、 `docker image build --help` で見ることができます。

例えばカレントディレクトリにDockerfileがある場合は、 `docker image build .` でビルドできますし、イメージに名前などをつけたい場合は、 `-t` オプションを利用して、 `docker image build -t demo-nginx:1.0 .` と実行し、イメージ名を **demo-nginx** に、タグ名を **1.0** にすることができます。

```
sample $ docker image build -t demo-nginx:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM ubuntu:latest
 ---> cd6d8154f1e1
Step 2/5 : MAINTAINER SUPAIKU2452
 ---> Running in f8dc2dbbb5bb
Removing intermediate container f8dc2dbbb5bb
 ---> 017f2e2dad51
Step 3/5 : RUN apt-get update && apt-get install -y -q nginx
 ---> Running in fa39c8c024a0
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB]
Get:3 http://security.ubuntu.com/ubuntu bionic-security/universe Sources [21.8 kB]
Get:4 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]

// 省略

Setting up nginx (1.14.0-0ubuntu1.1) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Removing intermediate container fa39c8c024a0
 ---> a494a2ec2c88
Step 4/5 : EXPOSE 80
 ---> Running in 372778581c36
Removing intermediate container 372778581c36
 ---> 4ffe58c1cbc5
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in 562dc8f02cc8
Removing intermediate container 562dc8f02cc8
 ---> cb54da9103eb
Successfully built cb54da9103eb
Successfully tagged demo-nginx:1.0
```

上記、名前をつけてbuildしたあと `docker image ls` をすると以下のように表示されます。

```shell
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-nginx                        1.0                 cb54da9103eb        2 minutes ago       186MB
```

### history コマンド
コマンド例は、 `docker image history [OPTIONS] IMAGE` です。OPTIONSは、 `docker image history --help` で見ることができます。

まずイメージの一覧を確認します。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-nginx                        latest              3c8815734199        24 minutes ago      186MB
```

次にnginxのイメージの履歴を確認します。 `-H` オプションは、人が見やすいフォーマットにしてくれるものです。

```
sample $ docker image history -H demo-nginx
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
3c8815734199        24 minutes ago      /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B
84342b8bb4c3        24 minutes ago      /bin/sh -c #(nop)  EXPOSE 80                    0B
848271193214        24 minutes ago      /bin/sh -c apt-get update && apt-get install…   102MB
fd2cd37fe5f4        25 minutes ago      /bin/sh -c #(nop)  MAINTAINER SUPAIKU2452       0B
cd6d8154f1e1        4 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           4 weeks ago         /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
<missing>           4 weeks ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   2.76kB
<missing>           4 weeks ago         /bin/sh -c rm -rf /var/lib/apt/lists/*          0B
<missing>           4 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B
<missing>           4 weeks ago         /bin/sh -c #(nop) ADD file:3df374a69ce696c21…   84.1MB
```

### import コマンド
コマンド例は、 `docker image import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]` です。OPTIONSは、 `docker image import --help` で見ることができます。

`import` コマンドは、 `docker container export` で作成したtarファイルをimportするために使用します。 `docker container export` は、export対象のコンテナ(ファイルシステム)のスナップショットのtarファイルを作成します。

以下は同一コンテナでvimのインストール前後にexportした結果(tarファイル)です。

```
sample $ ll
total 833672
-rw-r--r--  1 ozawa  staff        141 10  6 18:32 Dockerfile
-rw-------  1 ozawa  staff  174532096 10  8 17:28 export_demo-server.tar // 上記Dockerfileをbuildし、コンテナ化したものをexportした結果
-rw-------  1 ozawa  staff  230949888 10  8 17:37 export_demo-server_edited.tar // 上記Dockerfileをbuildし、コンテナ化した後にvimをインストールした後にexportした結果
```

上記をそれぞれimportすると、以下のようになります。

```
sample $ docker image import export_demo-server.tar demo-server-no-vim:latest
sha256:0d55b6bc91b440df16e90a3d67942b73b3301d34ba6d67660e4951eb0547f219

sample $ docker image import export_demo-server_edited.tar demo-server-added-vim:latest
sha256:aad52f29506d7d6e524d33a9dd65fcd354ff7f211cb97036fdf9aab34289ee92
```

`docker image ls` をすると、それぞれのイメージが作成されていることがわかります。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED              SIZE
demo-server-added-vim             latest              aad52f29506d        21 seconds ago       226MB
demo-server-no-vim                latest              0d55b6bc91b4        About a minute ago   171MB
```

### inspect コマンド
コマンド例は、 `docker image import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]` です。OPTIONSは、 `docker image inspect --help` で見ることができます。

buildコマンドのところで作成したnginxのイメージをinspectすると以下のように表示されます。

```
sample $ docker image inspect 3c8815734199
[
    {
        "Id": "sha256:3c8815734199e168382cff40931459d1188acf998db7bc5392b1aa85d467e3d2",
        "RepoTags": [
            "demo-nginx:latest"
        ],
        "RepoDigests": [],
        "Parent": "sha256:84342b8bb4c355e7ba39d7363f1946cb5d277086abb0f6a2fa2695263c33e55d",
        "Comment": "",
        "Created": "2018-10-08T06:30:20.78306975Z",
        "Container": "e91b47a8db3e0753a7b1665429a8c258f7b7cf8b94ef05d25743a7f49b473ef8",
        "ContainerConfig": {
            "Hostname": "e91b47a8db3e",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:84342b8bb4c355e7ba39d7363f1946cb5d277086abb0f6a2fa2695263c33e55d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "18.06.1-ce",
        "Author": "SUPAIKU2452",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:84342b8bb4c355e7ba39d7363f1946cb5d277086abb0f6a2fa2695263c33e55d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 186479280,
        "VirtualSize": 186479280,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/0df593449c5bf335e00965e46734511ef8227aedbfb5c447fd1ae57700596a87/diff:/var/lib/docker/overlay2/90ebf30f3ec17c9baec991f2efca51db83266184918ebb4751da8e56fc9546a0/diff:/var/lib/docker/overlay2/714e3f14178df4e6d3ad44d25b96c3596538d4c08b4a146b342ed6f5b8b991a5/diff:/var/lib/docker/overlay2/9cf9f6a55f59e271152c01e843a7dc1cc212a24bc7b1b6e854b9f346f9c27ba2/diff:/var/lib/docker/overlay2/d46ae2add4909f0513c1989cf9548dbfe9430c126816a394c0a991b4caf2984d/diff",
                "MergedDir": "/var/lib/docker/overlay2/925aa31424a1fd9d8f4d1a829922a42018e716930d009e0b597d6ac8b1a8a5e8/merged",
                "UpperDir": "/var/lib/docker/overlay2/925aa31424a1fd9d8f4d1a829922a42018e716930d009e0b597d6ac8b1a8a5e8/diff",
                "WorkDir": "/var/lib/docker/overlay2/925aa31424a1fd9d8f4d1a829922a42018e716930d009e0b597d6ac8b1a8a5e8/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:a30b835850bfd4c7e9495edf7085cedfad918219227c7157ff71e8afe2661f63",
                "sha256:6267b420796f78004358a36a2dd7ea24640e0d2cd9bbfdba43bb0c140ce73567",
                "sha256:f73b2816c52ac5f8c1f64a1b309b70ff4318d11adff253da4320eee4b3236373",
                "sha256:6a061ee02432e1472146296de3f6dab653f57c109316fa178b40a5052e695e41",
                "sha256:8d7ea83e3c626d5ef1e6a05de454c3fe8b7a567db96293cb094e71930dba387d",
                "sha256:5d9c3fd98a992236630b4d4f050ce3a5f8ed1e48d27ec3bd05ea86fff6df4210"
            ]
        },
        "Metadata": {
            "LastTagTime": "2018-10-08T06:30:20.84600717Z"
        }
    }
]
```

### load コマンド
コマンド例は、 `docker image load [OPTIONS]` です。OPTIONSは、 `docker image load --help` で見ることができます。

`load` コマンドは、 `docker image save` で作成したtarファイルをloadするために使用します。 `docker image save` は、save対象のイメージのスナップショットのtarファイルを作成します。

以下はimportにより作成されたイメージをsaveした結果(tarファイル)です。

```
total 825288
-rw-r--r--  1 ozawa  staff        141 10  6 18:32 Dockerfile
-rw-------  1 ozawa  staff  230958080 10  8 19:29 save_demo-server-added-vim.tar
-rw-------  1 ozawa  staff  174540288 10  8 19:28 save_demo-server-no-vim.tar
```

上記tarファイルを読み込むためにイメージを削除します。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              aad52f29506d        About an hour ago   226MB // さっき作成したイメージ
demo-server-no-vim                latest              0d55b6bc91b4        About an hour ago   171MB // さっき作成したイメージ

sample $ docker image rm demo-server-added-vim demo-server-no-vim
Untagged: demo-server-added-vim:latest
Deleted: sha256:aad52f29506d7d6e524d33a9dd65fcd354ff7f211cb97036fdf9aab34289ee92
Deleted: sha256:469c68558cd9a9c69d71fd5cc50bc72579cf91d509937936958b4f6913345bd8
Untagged: demo-server-no-vim:latest
Deleted: sha256:0d55b6bc91b440df16e90a3d67942b73b3301d34ba6d67660e4951eb0547f219
Deleted: sha256:f036da26d169c7210e72e11d1f22106015f25cd348734bb761559bb347116d24

sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
```

それぞれのtarファイルをloadします。

```
sample $ docker image load -i save_demo-server-no-vim.tar
f036da26d169: Loading layer [==================================================>]  174.5MB/174.5MB
Loaded image: demo-server-no-vim:latest

sample $ docker image load -i save_demo-server-added-vim.tar
469c68558cd9: Loading layer [==================================================>]  230.9MB/230.9MB
Loaded image: demo-server-added-vim:latest
```

`docker image ls` をすると、それぞれのイメージが読み込めていることがわかります。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              aad52f29506d        About an hour ago   226MB
demo-server-no-vim                latest              0d55b6bc91b4        About an hour ago   171MB
```

### ls コマンド
コマンド例は、 `docker image load [OPTIONS]` です。OPTIONSは、 `docker image ls --help` で見ることができます。

上記から登場しているので特に説明することはないかなと思います。お好みでオプションを利用してください。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              aad52f29506d        About an hour ago   226MB
demo-server-no-vim                latest              0d55b6bc91b4        About an hour ago   171MB
```

### prune コマンド
コマンド例は、 `docker image prune [OPTIONS]` です。OPTIONSは、 `docker image prune --help` で見ることができます。

`prune` はオプションにより挙動が異なります。まずはオプションなしを確認します。

```
sample $ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
```

**WARNING! This will remove all dangling images.** と出てきます。ここでの **dangling images** はどのイメージにも紐づかないイメージのことを指しています。とはいえどんな状態かわからないので、実際にその状態を再現します。

例えば以下のようなイメージがある時に、同じイメージ:タグ名で `docker image import` を実行します。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              ee073674632b        21 seconds ago      226MB
demo-server-no-vim                latest              0d55b6bc91b4        2 hours ago         171MB
```

以下のコマンドを実行します。コマンドが正常に終了したら、イメージ一覧を見てみましょう。

```
sample $ docker image import export/export_demo-server_edited.tar demo-server-added-vim latest
sha256:06c34cbf08d3ebcd4be20cbc83477e2f4d2bdf6c86aa9c760593727053e1c12b
```

先ほどあった、 IDが **ee073674632b** の名前とタグが `<none>` になっています。この状態が **dangling images** の状態です。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              06c34cbf08d3        6 seconds ago       226MB
<none>                            <none>              ee073674632b        2 hours ago         226MB
```

すでにイメージとタグ名が別のイメージに割り当てられた状態になっているので、元のイメージは何も使用されていない状態になります。
このような状態は、 `docker image pull` を実行した時に、名前やタグを別のイメージに割り当てた時に起こり得ます(おそらく公式のlatestをずっとpullしていたらなる)。

やっと本題にたどり着いたところで、pruneを実行します。

```
sample $ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:ee073674632bf765e66e7752c360a1acd97e332376864355a02ac48b05bce888

Total reclaimed space: 0B
```

イメージの一覧をみてみましょう。

```
sample $ docker image ls
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
demo-server-added-vim             latest              06c34cbf08d3        10 minutes ago      226MB
demo-server-no-vim                latest              0d55b6bc91b4        4 hours ago         171MB
```

先ほどの `<none>` が割り当たっていたIDのイメージが削除されていることがわかります。

では次に、コンテナで利用してないイメージを削除してみましょう。こちらは、 `-a` オプションを利用することで実行することができます。

今回はコマンドの挙動を見るために、停止中のコンテナを `docker container prune` で全て削除します。
**※停止中のものを全て削除するのでプロダクション環境やステージング環境などで安易に実行しないでください。責任は取れません。**

```
sample $ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
2ca16fdc81801ff71b323c44bd7d13abd3a491097a9f57043eb800546ff5a7ca
f2103f6d36b07e2e3201a5f1da76ee78818008646e104e6722bac171a3e5caf8
dd13d01a9ee69b6bad5d1eaf6aa5a4f86e821eeadb0ec08b1a6c9f39aa85b1c7
bce5308f4722bb2006df6485e31d9ddbfa9129c6c07fea3b30f9126caa2d5a11
9893a73091b7ba3296594010d019f3d87d0fe65139c76879156e69fe2ffbd359
bd09da33f56d7b005628a5f516d567d4d54f8ed03d14b8830f0b57bc82276ac3
0bf886e1cc2ac98f8ca1c68864f19353f3e949498378772d82b8e3db952fc3db
ffc88af6696f64abf777d000b9ec5733b2251bd06cf653d8560a042649601160
02712532c4333b768f4e047a66ac28765c94d8d1d1561c72b2566070fa746dcb
d5ac0d89c95aa61c1e0243f7ea8a7347a6d12ff6387b15471b0889e73f098483
38392afdb408432d2dfbc8d04810cb1b033ceca3f8d203376d372bb7c28cc60f
dfef09432d866f73e172aee9bab97b281142d77f5b6a914df3a2b9fe354d2b1f
fb61543e55e239ea5119a9daa6be9b7e856503d62875ee7c1a206e11e8dd2039
cf684f3c5629a3abbfa45b224612e9efac02608d07a692586f40deb65e61a81c
5e88c93fdc9029d807d8d076d6af8778babbdb131923959a2eb112dcbd00d0fe
2461594feb709960385ff520e7c76f6a6b1242fbf6096bb53876592c048d861a
d762dc1893fe38f14eeffdd9a9faf4a8ec0bf94ce4131712cee3aa3a614eabc9
fa766d79284fda3578667b857353ebbfe5dfc7ae52a543540303ba4047546632
// 省略

Total reclaimed space: 613.7MB
```

結構消えましたね...
念のため、 `docker container ls -a` で残骸がないかみてみましょう。

```
sample $ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

ないことを確認したので、次に `docker image prune -a` でイメージを削除します。

```
sample $ docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: busybox:latest
untagged: busybox@sha256:2a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bddd8d92465812
untagged: supaiku2452/docker-whale:latest
untagged: supaiku2452/docker-whale@sha256:62452ed780abda4da8e1c48156eea67d6e2a28d674c80f92a9b7f0a2a8b1778a
deleted: sha256:152bbed271a850553e2aa2b03106fb162ad741f3cfa6468087665090d8557e6a
deleted: sha256:33c8eb6b8784065b2a3ffa22185f3da89ddcaf9da9d5f5be4ce66f189f4d7ba9
untagged: oraclelinux:latest
untagged: oraclelinux@sha256:30769a789138a2220cf7165173f88d86dde10bf80a5fc79c2d9617f99936d91d
untagged: node:10.10.0-alpine
untagged: node@sha256:fcab88e96877f3a592be65131ca08d613db8558fefbc3fcc988876fd3b5a447d
untagged: davide-docker_davide-mysql-data:latest
deleted: sha256:9af8f7b8ec36f3128a5693d07cdfdd4bb25e3629aece0df6176fccd50a7f94ae
deleted: sha256:4e9b2095b3c88ef54604a5f493e3ac3da6f3a5f642539bf46ad101bc4b4a3242
deleted: sha256:59788edf1f3e78cd0ebe6ce1446e9d10788225db3dedcfd1a59f764bad2b2690
deleted: sha256:8a788232037eaf17794408ff3df6b922a1aedf9ef8de36afdae3ed0b0381907b
untagged: centos:latest
untagged: centos@sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf
deleted: sha256:5182e96772bf11f4b912658e265dfe0db8bd314475443b6434ea708784192892
deleted: sha256:1d31b5806ba40b5f67bde96f18a181668348934a44c9253b420d5f04cfb4e37a
untagged: demo-server-added-vim:latest
deleted: sha256:06c34cbf08d3ebcd4be20cbc83477e2f4d2bdf6c86aa9c760593727053e1c12b
deleted: sha256:469c68558cd9a9c69d71fd5cc50bc72579cf91d509937936958b4f6913345bd8

// 省略

Total reclaimed space: 3.47GB
```

全部消えましたね...
念のため、 `docker image ls -a` で残骸がないかみてみましょう。

```
sample $ docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
```

なにもありませんね。

pruneコマンドですが、一括削除コマンドになるのでコマンド実行前に必ず確認メッセージが表示されます。

```
sample $ docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y

sample $ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
```

`-a` の有無で処理内容が変わるのでメッセージも変わっていますね。上記でも注意書きしていますが、このコマンドの利用には気をつけてください(特に **-a** オプション)。

### pull コマンド
コマンド例は、 `docker image pull [OPTIONS] NAME[:TAG|@DIGEST]` です。OPTIONSは、 `docker image pull --help` で見ることができます。

今回は[redis](https://hub.docker.com/_/redis/)のイメージを取得します。

```
sample $ docker image pull redis
Using default tag: latest
latest: Pulling from library/redis
802b00ed6f79: Already exists
8b4a21f633de: Pull complete
92e244f8ff14: Pull complete
fbf4770cd9d6: Pull complete
1479f3bcce09: Pull complete
1d0259f5f9fc: Pull complete
Digest: sha256:3af96d7643f46b9cfb475b6e26720db8ac00cbc7396d5b74fe7b0080f6df337e
Status: Downloaded newer image for redis:latest
```

イメージが取得できたか確認します。

```
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
redis               latest              0a153379a539        6 days ago          83.4MB
```

### push コマンド
コマンド例は、 `docker image push [OPTIONS] NAME[:TAG]` です。OPTIONSは、 `docker image push --help` で見ることができます。

実際にDockerfileから任意のイメージを作成し、個人のDocker Hubにpushします。
※Docker Hubがない場合は、事前に用意しておくといいでしょう。

Docker Hubはこんな感じです。
![supaiku2452_-_Docker_Hub_bef.png](https://qiita-image-store.s3.amazonaws.com/0/170140/263b3ad5-354b-7f4e-aeb3-b545da5e2808.png)

まず、以下のように適当なDockerfileを用意します。

```
FROM ubuntu:latest

MAINTAINER SUPAIKU2452

RUN apt-get update && apt-get install -y -q nginx

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
```

Dockerfileをbuildコマンドでビルドし、イメージを作成します。

```
sample $ docker image build -t supaiku2452/demo-nginx .
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM ubuntu:latest
latest: Pulling from library/ubuntu
124c757242f8: Pull complete
9d866f8bde2a: Pull complete
fa3f2f277e67: Pull complete
398d32b153e8: Pull complete
afde35469481: Pull complete
Digest: sha256:de774a3145f7ca4f0bd144c7d4ffb2931e06634f11529653b23eba85aef8e378
Status: Downloaded newer image for ubuntu:latest
 ---> cd6d8154f1e1
Step 2/5 : MAINTAINER SUPAIKU2452
 ---> Running in acab6be016c9
Removing intermediate container acab6be016c9
 ---> d4070df0a86b
Step 3/5 : RUN apt-get update && apt-get install -y -q nginx
 ---> Running in 2bf2a24ca425
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
// 省略
Step 4/5 : EXPOSE 80
 ---> Running in ce5dc392cc26
Removing intermediate container ce5dc392cc26
 ---> 368d0aa9e19a
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in bbaa38257dd8
Removing intermediate container bbaa38257dd8
 ---> 7e2fc15722d5
Successfully built 7e2fc15722d5
Successfully tagged supaiku2452/demo-nginx:latest
```

イメージが作成されているか確認します。

```
sample $ docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
supaiku2452/demo-nginx   latest              7e2fc15722d5        5 minutes ago       186MB
```

このイメージをpushします。

```
sample $ docker image push supaiku2452/demo-nginx
The push refers to repository [docker.io/supaiku2452/demo-nginx]
3a3598b96a65: Pushed
8d7ea83e3c62: Mounted from library/ubuntu
6a061ee02432: Mounted from library/ubuntu
f73b2816c52a: Mounted from library/ubuntu
6267b420796f: Mounted from library/ubuntu
a30b835850bf: Mounted from library/ubuntu
latest: digest: sha256:54850aa54d302fcbfa80e81de4f9baed4834e3b2bb23af525b0df08416d71f6c size: 1569
```

では、Docker Hubの方にイメージがpushされているか確認します。

![supaiku2452_-_Docker_Hub_aft.png](https://qiita-image-store.s3.amazonaws.com/0/170140/ddb300a3-2377-0df5-a579-b4c220a596f8.png)

Docker Hub に登録されていることが確認出来ました。

### rm コマンド
コマンド例は、 `docker image rm [OPTIONS] IMAGE [IMAGE...]` です。OPTIONSは、 `docker image rm --help` で見ることができます。

先ほどpullしたredisのイメージを削除します。

まず、イメージの一覧を確認します。

```
sample $ docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
redis                    latest              0a153379a539        6 days ago          83.4MB
```

IMAGE ID(0a153379a539) をrmコマンドで削除します。

```
sample $ docker image rm 0a153379a539
Untagged: redis:latest
Untagged: redis@sha256:3af96d7643f46b9cfb475b6e26720db8ac00cbc7396d5b74fe7b0080f6df337e
Deleted: sha256:0a153379a539d294a7971775605b19a1943bd7acb7cd48d8e7e2fc555fc25239
Deleted: sha256:9fb297a388adaae3e806729c4aa4b34d8926b57825bf75c6f6462fe5b2418b0a
Deleted: sha256:e8237a63680e91814c2187d36bf877b77bcdbe32f039e3830b971899ba3d9066
Deleted: sha256:ee3e8a7f98978d885f024af810e81c5111010a5ad04a506e108b8164c14ecc53
Deleted: sha256:19261f688dac95e95c456e918a4374328ce0f6e3fbccd8b8bf2aaf7fa64caf8f
Deleted: sha256:8a43eb91122ffb8c673e3c1c8191ef02af80d23b14758d3be28a09631bb8ec14
```

イメージが削除されたか確認します。

```
sample $ docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
```

イメージが削除されています。rmコマンドでは、複数のイメージを指定して一括で消すことも可能です(例: `docker image rm imageA imageB imageC` )。


### save コマンド
コマンド例は、 `docker image save [OPTIONS] IMAGE [IMAGE...]` です。OPTIONSは、 `docker image save --help` で見ることができます。

saveコマンドを実行するとイメージの標準出力(ファイル指定がない場合は、標準出力)またはtarファイルを出力することが出来ます。
ここで、saveコマンドで出力されるtarファイルはイメージのレイヤー情報を含むファイルです。

実際にsaveコマンドでtarファイルを出力します。

```
sample $ docker image save -o nginx_saved.tar nginx
```

作成したtarファイルを確認します。

```
sample $ tar tvf nginx_saved.tar
drwxr-xr-x  0 0      0           0 10  3 04:20 0fd2125fb1639856cb4a4ddaf556bdbdcdac35f12ba2b5f4ef60632cdad3d1a1/
-rw-r--r--  0 0      0           3 10  3 04:20 0fd2125fb1639856cb4a4ddaf556bdbdcdac35f12ba2b5f4ef60632cdad3d1a1/VERSION
-rw-r--r--  0 0      0         477 10  3 04:20 0fd2125fb1639856cb4a4ddaf556bdbdcdac35f12ba2b5f4ef60632cdad3d1a1/json
-rw-r--r--  0 0      0    54350848 10  3 04:20 0fd2125fb1639856cb4a4ddaf556bdbdcdac35f12ba2b5f4ef60632cdad3d1a1/layer.tar
drwxr-xr-x  0 0      0           0 10  3 04:20 5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca/
-rw-r--r--  0 0      0           3 10  3 04:20 5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca/VERSION
-rw-r--r--  0 0      0         401 10  3 04:20 5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca/json
-rw-r--r--  0 0      0    58436096 10  3 04:20 5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca/layer.tar
-rw-r--r--  0 0      0        6022 10  3 04:20 be1f31be9a87cc4b8668e6f0fee4efd2b43e5d4f7734c75ac49432175aaa6ef9.json
drwxr-xr-x  0 0      0           0 10  3 04:20 bfa4e71a7c53e0ff65c2b52c6d797a1f449b5f61f1089bc5ce371c6337c6ed09/
-rw-r--r--  0 0      0           3 10  3 04:20 bfa4e71a7c53e0ff65c2b52c6d797a1f449b5f61f1089bc5ce371c6337c6ed09/VERSION
-rw-r--r--  0 0      0        1684 10  3 04:20 bfa4e71a7c53e0ff65c2b52c6d797a1f449b5f61f1089bc5ce371c6337c6ed09/json
-rw-r--r--  0 0      0        3584 10  3 04:20 bfa4e71a7c53e0ff65c2b52c6d797a1f449b5f61f1089bc5ce371c6337c6ed09/layer.tar
-rw-r--r--  0 0      0         355  1  1  1970 manifest.json
-rw-r--r--  0 0      0          88  1  1  1970 repositories
```

なにやら色々入っていますが、このディレクトリ構成は以下のようになっています。

- 0fd2125fb1639856cb4a4ddaf556bdbdcdac35f12ba2b5f4ef60632cdad3d1a1 → レイヤー情報が格納されたディレクトリ
- 5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca → レイヤー情報が格納されたディレクトリ
- bfa4e71a7c53e0ff65c2b52c6d797a1f449b5f61f1089bc5ce371c6337c6ed09 → レイヤー情報が格納されたディレクトリ
- be1f31be9a87cc4b8668e6f0fee4efd2b43e5d4f7734c75ac49432175aaa6ef9.json → イメージ情報が書かれたjsonファイル
- manifest.json → このディレクトリの構成について書かれたjson
- repositories → リポジトリ情報が書かれたファイル

Dockerのレイヤー構成については、[こちら](http://docs.docker.jp/engine/userguide/storagedriver/imagesandcontainers.html)に詳しく書かれていますが、ざっくり説明すると、変更があった場合はベースのレイヤーの上にイメージが重ねられます。
今回の場合は、ベースが **5bfae0e2ea842897fc3f2831cf24994ffa966ffe3746e4a57529d680334001ca** でこれの上に変更分のレイヤーが積み重ねられている状態です。

すでにloadコマンドについて説明しましたが、saveではこれらのレイヤー情報を保持しているため、名前やタグなども指定することなく元々のイメージの情報をそのままloadすることができるのです。

### tag コマンド
コマンド例は、 `docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]` です。OPTIONSは、 `docker image tag --help` で見ることができます。

イメージに新たなタグを設定することが出来ます。この時、SOURCE_IMAGEとTARGET_IMAGEで参照するイメージは同一であるためイメージIDは変わりません。

ubuntuのイメージにタグを設定します。

イメージの一覧を確認します。

```
sample $ docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
ubuntu                   latest              cd6d8154f1e1        4 weeks ago         84.1MB
```

名前を **supaiku2452/sample-ubuntu** タグを **latest** に設定します。

```
sample $ docker image tag ubuntu:latest supaiku2452/sample-ubuntu:latest
```

イメージの一覧を確認します。

```
sample $ docker image ls
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
supaiku2452/sample-ubuntu   latest              cd6d8154f1e1        4 weeks ago         84.1MB
ubuntu                      latest              cd6d8154f1e1        4 weeks ago         84.1MB
```

イメージIDが同一で別タグのイメージが出来ていることがわかります。

### **import/export** と **load/save** の違い
import/exportとload/saveの違いは、イメージにする時に元のイメージ情報の有無です。

import/exportは、export時にコンテナのスナップショットをtarファイルや標準出力にしているので、元のイメージ情報は欠落します。そして、そのままimportによりイメージ化を行うため、元のイメージ情報は引き継がれず、新しいイメージ情報が作成されます。

load/saveは、save時にイメージのレイヤー情報も含めてtarファイルや標準出力にしているので、元のイメージ情報が保持されています。そして、その内容をloadするため(あくまでも読み込みであり、作成はしない)、元のイメージ情報が引き継がれたイメージが読み込まれます。

これらはコンテナやイメージのバックアップ戦略により、用いるコマンドがことなりそうです(筆者がまだこういう問題に当たっていないため、推測になります)。
単純にコンテナのスナップショットだけ欲しい場合は、import/exportだけで良いですし、オフライン環境でイメージの管理を行いたい場合は、laod/saveになるかと考えています。

以上でimageコマンドのまとめは終わりです。
次回は、containerコマンドについてまとめたいと思います。

## まとめ一覧
[Dockerの基礎をまとめてみた ~ 第一章：コンテナ？Dockerとは？](https://qiita.com/supaiku2452/items/8b06b774c0e2fce7df92)
[Dockerの基礎をまとめてみた ~ 第二章：Dockerの基本操作](https://qiita.com/supaiku2452/items/eefdb8ebf106ac579bfa)
Dockerの基礎をまとめてみた ~ 第三章：Dockerコマンド - image編
[Dockerの基礎をまとめてみた ~ 第四章：Dockerコマンド - container編](https://qiita.com/supaiku2452/items/da44b05c4ba4ec13bccf)