Docker を使う（python のイメージで色々確認してみる）

[前回の記事](https://qiita.com/landwarrior/items/6e6c43e3007a5820bdb5) の続きです。
前回は Docker をインストールして CentOS の上で CentOS のイメージを動かしました。
今回は、次回につながる Python のイメージを使って遊びたいと思います。
`docker build` については、また次回に説明できれば・・・
なお、環境は前回の記事から引き続き使用します。

# Docker Hub

前回も多少説明しましたが、Docker で使えるイメージがたくさん公開されているところが [Docker Hub](https://hub.docker.com/) になります。
例えば、Docker Hub の上部検索窓に「python」と入力してエンターキーを押すと↓
![dockerhub1.png](https://qiita-image-store.s3.amazonaws.com/0/179043/f5f1d4c1-2470-1b85-662a-f9c92d786c4a.png)

以下のような画面になります。
![dockerhub2.png](https://qiita-image-store.s3.amazonaws.com/0/179043/377b44ae-058c-787e-8b6c-78ad1583b9d3.png)

一番上の python をクリックしてみると、python のページが表示されますよね。
![dockerhub3.png](https://qiita-image-store.s3.amazonaws.com/0/179043/d293117c-0ab3-a38c-7dfe-d87ddc47101e.png)

ここで、およそ使うタグの一覧を確認することができます。
また、「TAGS」のタブをクリックすれば、存在するタグがたくさん見れます。
執筆時点で 639 個もあるので多すぎ・・・

# docker pull してみよう

前回華麗にスルーしましたが、docker イメージをローカルに持ってくるためには `docker pull` というコマンドを使います。
まあ `docker run` する時にローカルにないイメージを指定していたら自動的に docker pull するので明示的にやらなくても大丈夫ですが・・・

それではまず、python のイメージを pull してみます。
とりあえず最新のイメージでよければ、以下のように実行します。

```
[root@localhost vagrant]# docker pull python:latest
```
なにやら動いてイメージが pull できました。
`docker images` コマンドで確認してみます。

```
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              latest              338b34a7555c        25 hours ago        927MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
```
なんか最新版が取れたっぽいですね。
今度は別のタグがついたイメージを取ってきてみます。

```
[root@localhost vagrant]# docker pull python:3.7
```
もう一度確認してみます。

```
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.7                 338b34a7555c        25 hours ago        927MB
python              latest              338b34a7555c        25 hours ago        927MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
```
おっと、どうやら `latest` と `3.7` はイメージIDが同じなので実体が同じようです。
これは、よく読むと Docker Hub の先ほどの python のページのタグの説明から判断できます。

では次に、以下のコマンドを実行してみます。

```
[root@localhost vagrant]# docker pull python:3.7-alpine
```
では、イメージを確認してみます。

```
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.7                 338b34a7555c        25 hours ago        927MB
python              latest              338b34a7555c        25 hours ago        927MB
python              3.7-alpine          6772938ddd91        36 hours ago        86.7MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
```
異なるイメージIDのものが取得できました。
しかし、よく見てください。サイズが10倍も違う・・・
`alpine` とついているものは、余計なものを極限までそぎ落とした軽量版、のようです。
そういう定義なのかはよく分かっていないのですが・・・そう解釈しています。

ついでにもう一つ pull してみます。

```
[root@localhost vagrant]# docker pull python:3.6.3-onbuild
```
この `onbuild` がついたタグはちょっと特殊で、Dockerfile を使って `docker build` をするとき、Dockerfile 内で `pip install` を書かなくても Dockerfile と同じディレクトリに requirements.txt があると自動的にインストールをするようになっています。
python3.7 から onbuild のものは無くなったようなので、覚える必要はもうないですが・・・

python ばっかりでごめんなさい。今一番仕事で使っている言語なもので。

で、イメージを確認してみます。

```
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.7                 338b34a7555c        26 hours ago        927MB
python              latest              338b34a7555c        26 hours ago        927MB
python              3.7-alpine          6772938ddd91        36 hours ago        86.7MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
python              3.6.3-onbuild       2c3b4004c956        14 months ago       691MB
```
onbuild のものは一番でかいのかと思いましたが、そうでもなかったです。



# docker run してみよう

ではでは、それぞれのイメージを使ってコンテナを立ち上げてみましょう。
まずはとりあえず `/bin/bash` での起動です。

```
[root@localhost vagrant]# docker run -it --rm python:latest /bin/bash
root@1d2b7fc57d2c:/#
```
当然起動できます。
今回新たに `--rm` をつけていますが、これはコンテナの終了時、自動的にコンテナを削除してくれます。
試しに `exit` で抜けると、コンテナが残っていないのが分かります。

```
root@1d2b7fc57d2c:/# exit
exit
[root@localhost vagrant]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost vagrant]# 
```
次に、`alpine` のイメージで起動してみます。

```
[root@localhost vagrant]# docker run -it --rm python:3.7-alpine /bin/bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown.
```
起動できませんでした。
`alpine` のものには、bash すらないということですね。
`/bin/sh` ならあります。

```
[root@localhost vagrant]# docker run -it --rm python:3.7-alpine /bin/sh
/ #
```
ただ、超絶使いづらいです。
Back Space キーも Delete キーも Tab キーも使えないです。クソですね。

じゃあ次に、それぞれにどういった python モジュールが含まれているかを確認してみます。
まずは最新から。

```
[root@localhost vagrant]# docker run --rm python:latest pip list
Package    Version
---------- -------
pip        19.0.1 
setuptools 40.8.0 
wheel      0.32.3
```
今回は標準入力に入る必要がないので、`-it` はつけていません。
だいぶ新しいのが入っていますね。
次に、alpine です。

```
[root@localhost vagrant]# docker run --rm python:3.7-alpine pip list
Package    Version
---------- -------
pip        19.0.1 
setuptools 40.8.0 
wheel      0.32.3 
```

以外にも、 python 自体は同じようです。
ちなみに `3.6.3-onbuild` はそもそも古いので、挙動が違います。

```
[root@localhost vagrant]# docker run --rm python:3.6.3-onbuild pip list
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
pip (9.0.1)
setuptools (38.2.4)
wheel (0.30.0)
You are using pip version 9.0.1, however version 19.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```
python のバージョンが違うんだから当然ですね。

```
[root@localhost vagrant]# docker run --rm python:latest python -V
Python 3.7.2
[root@localhost vagrant]# docker run --rm python:3.7-alpine python -V
Python 3.7.2
[root@localhost vagrant]# docker run --rm python:3.6.3-onbuild python -V
Python 3.6.3
```

ところで、なぜ python のバージョンが同じでもイメージのサイズが10倍も違うのでしょうか？
それは、python のイメージといっても、実際には Debian というOS上に python が入っているからです。

```
[root@localhost vagrant]# docker run --rm python:latest cat /etc/debian_version
9.7
```
で、alpine はというと。

```
[root@localhost vagrant]# docker run --rm python:3.7-alpine cat /etc/debian_version
cat: can't open '/etc/debian_version': No such file or directory
```
ありません。
実はこの記事を書きながら調べていて知ったのですが。。。
`alpine` は、OSの名前のようです。
[Wikipediaの説明](https://ja.wikipedia.org/wiki/Alpine_Linux) を参照。

このOSが軽いため、イメージも軽いようですね。

```
[root@localhost vagrant]# docker run --rm python:3.7-alpine cat /etc/alpine-release
3.9.0
```
バージョンはこれですかね。

とまあ、調べながら記事を書いていると思わぬ発見もあってなかなか楽しいですね(笑)
あとは後始末しておきます。

```
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.7                 338b34a7555c        26 hours ago        927MB
python              latest              338b34a7555c        26 hours ago        927MB
python              3.7-alpine          6772938ddd91        36 hours ago        86.7MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
python              3.6.3-onbuild       2c3b4004c956        14 months ago       691MB
[root@localhost vagrant]# docker rmi `docker images -q`
Untagged: centos:centos7
Untagged: centos@sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Deleted: sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb
Deleted: sha256:071d8bd765171080d01682844524be57ac9883e53079b6ac66707e192ea25956
Untagged: python:3.6.3-onbuild
Untagged: python@sha256:da0be030a4713834375a17b4444dea96a87735a477adda8fe0d90615b7dd7a68
Deleted: sha256:2c3b4004c95687a2aefda3f4315dcf1fcf7a92d0b39e5e5c6d2b0988a38d8c89
Deleted: sha256:54ed58a604f7683ac68847312ba0ebae4e59fa0de39d83f88f345040aa94d816
Deleted: sha256:b5dda5ba8e3841e7ab0caa5ab33ade348c75f692af130d835599452993b18cb6
Deleted: sha256:a88988375383b9b10dd08db90fd15c30dc513194d91681867dc69abda6d56ef7
Deleted: sha256:9dc41a1248aa0aaf39e78986cf08284a7b66b0e8afbbefe53669770a3f628b0b
Deleted: sha256:6cbeff72f6ffcfda8ef666967dbd24b55f75f3be0604adfb2c4a48f4a5f10726
Deleted: sha256:a176968aca6e2da9dde867a49fcfb03e84f3a003481cb4c990ae45d551e686bd
Deleted: sha256:ccfcaf8fb471a2ec475db4fe91958b532e8cc1ba84ac42c51cb484346dc8ffc5
Deleted: sha256:7152b3dd92f68f075f10409f8a0060cc1e2cfe05bc39e9066d6962ab4fe16ccc
Deleted: sha256:4bcdffd70da292293d059d2435c7056711fab2655f8b74f48ad0abe042b63687
Error response from daemon: conflict: unable to delete 338b34a7555c (must be forced) - image is referenced in multiple repositories
Error response from daemon: conflict: unable to delete 338b34a7555c (must be forced) - image is referenced in multiple repositories
Error response from daemon: conflict: unable to delete 6772938ddd91 (must be forced) - image is being used by stopped container 7eac290f4128
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.7                 338b34a7555c        26 hours ago        927MB
python              latest              338b34a7555c        26 hours ago        927MB
python              3.7-alpine          6772938ddd91        36 hours ago        86.7MB
[root@localhost vagrant]# docker rmi -f `docker images -q`
Untagged: python:3.7
Untagged: python:latest
Untagged: python@sha256:5e790d7897ba75a8820e3d2d970ddd50799c8e92ba9e6f3c4987976c594b96b3
Deleted: sha256:338b34a7555c2b6a35ca4093fd5a06684116f9adebc9efcbb7141e5261ef3f38
Deleted: sha256:7703ce3dc9d4b078ddc24d8e86c508e028de147ad2fd300b337ddf9634b1e566
Deleted: sha256:70cea1735c6327330cf2c69a48fa543b6f83de73288228047a579c6b31ddcf17
Deleted: sha256:3d46a7823c655242fec7260b8e77a19e3ddf954555f11e91f983a84a0c4b01b2
Deleted: sha256:9f1a83701a94dae5b5546c0cc5d4af12fc215002b79437cef0320c586bd959a7
Deleted: sha256:6fbd9662db012d50f620a1444c898914c09b7377285a35d7ac6e2b1d0db85a8f
Deleted: sha256:39496f7d4f99c499b3c87643953d7b5243cc8a05ed9aad9cf1f404633cf4f8ea
Deleted: sha256:ac00eef3f557ea71d47b65f3112c0c3b6ae7113153b7205a94bedc496103a6c8
Deleted: sha256:8f0ebc672b43403012c586feeac72ec83ce8347faab22a2826b952968aefc3d6
Deleted: sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303
Untagged: python:3.7-alpine
Untagged: python@sha256:9e18fe152ba5bc64ff0c572574787536bc96b6b84826fd72600ead067899a675
Deleted: sha256:6772938ddd9146358932e80d0e3833b9055914060e0102c1288f59553f2b9f46
Error: No such image: 338b34a7555c
[root@localhost vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[root@localhost vagrant]# 
```
イメージIDが同じで複数のタグがあると `docker rmi` で削除できないので、`-f` オプションをつけて強制削除をしています。


# 最後に

前回と今回で、イメージやコンテナについては使い方が分かったのではないでしょうか？
次回こそは、`docker build` でオリジナルのイメージを作成したいと思います。

ようやく続編を書きました↓
[Docker を使う（docker build でオリジナルのイメージを作成する）](https://qiita.com/landwarrior/items/5cfbf2ce07be812e0907)