Dockerで色々やってみる（Image取得編）

# 概要
前回、Windows10にDocker Desktopをインストールして、いろいろ基本的な操作を確認したので、今回はもう一歩踏み込んでDockerを操作することを「自己整理」したいと思います。まずは、Imageの整理。（ただしDockerfileは除外）

前回の記事は下記。

https://qiita.com/TAKANEKOMACHI/items/f1aaa378d93b4ace9513

まとめは下記。

https://qiita.com/TAKANEKOMACHI/items/a890fc4f3a132828f62b

# 前提条件
+ Windows10にDocker Desktopがインストールされている状態

# Docker Hubを見てみる

Docker Hubには、Containerを作るためのImageのLibraryとして様々なImageが提供されています。

https://hub.docker.com/search?q=

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/16da9776-e911-ea2a-cdc0-e19219ef0a2f.png)

Dockerに触り始めた人だと、VirtualBoxやVM Wareのように「いろんなOSを選択できるんだね」と思いがちですが、よく見ると、OSよりもミドルウェアの方が多いですよね？
間隔的に、DockerでMySQLを使いたいと思ったら、「Ubuntu」などのOSを選択して、そこに「MySQL」を入れて・・・

違いますっ！！！

Dockerに「MySQL」のContainerを作ればMySQLが使えるんですっ！
OSを選択するのは、下記の「特殊」な性癖の人だけです。
+ OS自体を触りたい人
+ ミドルウェアを自作したり、カスタマイズしたい人

なので、例えばLAMP（Linux、Apache、MySQL、PHP）のような構成を作る場合、Dockerで「Apache」と「MySQL」の2つのContainerを作って終わりです。
（多少語弊がありますが・・・）

ただ、いろいろ見ていくと「AWS」でしか触れないAmazonLinux2とか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/2174f376-070d-2566-54d8-79d012b0165d.png)

DockerにDocker、、、みたいな混乱必至のようなものとか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/075f276e-71a2-4a7c-1e51-b29ca0bd3f61.png)

一通り眺めているだけでも、「ちょ、、、、ちょっと触ってみようかな。どうせすぐ消せるし」みたいな気分になってきます。

# Dockerのコマンドを把握する

前回記事でも軽く出してますが、PowerShell等で「docker」と入力するといろいろ出てきます。
```powershell:powershell
PS C:\> docker

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default
                           "C:\\.docker")
  -c, --context string     Name of the context to use to connect to the
                           daemon (overrides DOCKER_HOST env var and
                           default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default
                           "C:\\.docker\\ca.pem")
      --tlscert string     Path to TLS certificate file (default
                           "C:\\.docker\\cert.pem")
      --tlskey string      Path to TLS key file (default
                           "C:\\.docker\\key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.8.2)
  compose*    Docker Compose (Docker Inc., v2.6.0)
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  sbom*       View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan*       Docker Scan (Docker Inc., v0.17.0)
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
```

## Dockerのバージョンを確認する（> docker --version)
まずは、基本的なコマンドです。

```powershell:powershell
PS C:\> docker --version
Docker version 20.10.16, build aa7e414
```

お気づきだと思いますが、「Docker」のバージョン（上記）と、「Docker Desktop」のバージョン（下記）は別物です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/b2017125-93c4-f3d5-fbe0-bce1f9425c5b.png)

「Docker」のバージョンは「Docker Engine」のバージョンだと思ってください。
リリースノートを見るときは、「Docker Engine」と「Docker Desktop」のところを見ることになります。

https://docs.docker.com/release-notes/

なお、「Docker Engine」単体をUpgradeするコマンドはありません（たぶん）。

## DockerのImage（> docker image）
DockerのImageを管理するコマンドです。

```powershell:powershell
PS C:\> docker image --help

Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.
```

### Docker ImageをHubから取得する（> docker image pull)
まずは、前回の記事でもサンプルとしていた「ubuntu」を取得することにしましょう。

UbuntuのImageを開きます。

https://hub.docker.com/_/ubuntu

ポイントは、下記の箇所です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/e246e313-7853-4748-9c34-3941992a5aa0.png)

とりあえず、「Dockerfile」はどこかで説明するので、今は割愛しますが、Ubuntuと言ってもいろんなバージョンがあります。
ここを見ると、14系(trusty)～22.10系(kinetic)などが記載されています。

勘のいい人は気づいたと思いますが、Docker DesktopからUbuntuを選択して「Run」した際に「ubuntu:latest」と表示されていましたが、
「latest」は「22.04」の箇所に書かれているので、DLされたImage、つまり起動したContainerは「Ubuntu22.04」だったことになります。

なので、ここで取得するImageは、「22.04」ではないものにしましょう。
とりあえず無難に「18.04（bionic)」にしましょうか。

```powershell:powershell
PS C:\> docker image pull ubuntu:bionic
bionic: Pulling from library/ubuntu
09db6f815738: Pull complete
Digest: sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af
Status: Downloaded newer image for ubuntu:bionic
docker.io/library/ubuntu:bionic
PS C:\>
```

※今回「ubuntu:bionic」としましたが、別に「ubuntu:18.04」でも「ubuntu:bionic-20220531」でも良いです。
　要は「ubuntu」＋「:」＋タグ名　になってればOK。

ちなみに、Docker Imageは、Officialで頻繁に更新されます。
ただ、「タグ名」は「ubuntu:bionic-20220531」のような場合以外変わりません。

では、ローカルにあるImageを更新したい場合はどうするか？（削除して再取得？）
、、、普通に、もう一度pullすればOKです。
```powershell:powershell
PS C:\> docker image pull ubuntu:bionic
bionic: Pulling from library/ubuntu
Digest: sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af
Status: Image is up to date for ubuntu:bionic
docker.io/library/ubuntu:bionic
```


### ローカルに存在するImageのリストを確認する（> docker image ls）
Docker Imageを確認します。
前回の記事で「ubuntu:latest」がDLされて、前項で「ubuntu:bionic」がDLされているので2つあればOKです。

```powershell:powershell
PS C:\> docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    27941809078c   10 days ago   77.8MB
ubuntu       bionic    ad080923604a   10 days ago   63.1MB
PS C:\>
```

一応、載せておきますがImageの確認はDocker Desktopも同期されているので確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/65db91fe-742d-a157-6c61-278368d8f894.png)

余談ですが、下記でも同じ情報が取得できます。
```powershell:powershell
PS C:\> docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    27941809078c   10 days ago   77.8MB
ubuntu       bionic    ad080923604a   10 days ago   63.1MB

PS C:\> docker image list
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    27941809078c   10 days ago   77.8MB
ubuntu       bionic    ad080923604a   10 days ago   63.1MB
```

### 使っていないImageを廃棄する（> docker image rm）
削除できるのは、このImageで作成されたContainerが無いことが条件です。
Containerは「起動」していなくても「存在」していれば削除できません。

例えば、「ubuntu:latest」でContainerを起動して、停止させます。
```powershell:powershell
PS C:\> docker run -it ubuntu:latest
root@89b3f9ec5f9b:/# exit
exit
```

Docker Desktop上はImageは「IN USE」と表示されてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/b85ece51-889b-b855-f2d3-0f6fffd63efa.png)

Containerは、停止させているので下記のようになってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/01e1a712-cad4-76e9-1c56-dbe10c70afc4.png)

この状態でImageは削除できませんよ。
ということです。

```powershell:powershell
PS C:\> docker image rm 27941809078c
Error response from daemon: conflict: unable to delete 27941809078c (must be forced) - image is being used by stopped container 89b3f9ec5f9b
```

では、Containerを作っていない「ubuntu:bionic」は？というと
```powershell:powershell
PS C:\> docker image rm ad080923604a
Untagged: ubuntu:bionic
Untagged: ubuntu@sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af
Deleted: sha256:ad080923604aa54962e903125cd9a860605c111bc45afc7d491cd8c77dccc13b
Deleted: sha256:95129a5fe07e89c1898dc40a027b291d5fe33a67b35a88f0f0eaf51ea691f0b5
```

削除できましたね。

### 使っていないImageを廃棄する（> docker image prune）
※このコマンドは、以前使っていたときにはなかったな・・・

「prune」ってなんじゃい？スモモ？
と思って調べてみたら「余分な枝を切り落とす」という意味があり、そこから「余分なものを削除する」という意味になるようです。
「ダイエット」も「prune」とかいうのかな？ｗ

とりあえず、「ubuntu:latest」がContainerと繋がってるので、他に繋がってないImageを用意します。
```powershell:powershell
PS C:\> docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       latest    27941809078c   10 days ago    77.8MB
ubuntu       bionic    ad080923604a   10 days ago    63.1MB
ubuntu       xenial    b6f507652425   9 months ago   135MB
```

Docker Desktopから見るとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/964a1115-cad5-0558-8fd0-202d3e9c54e8.png)

「余計な枝（Image）」は、2つですね・・・
```powershell:powershell
PS C:\> docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
```

ぬ？消えないじゃん・・・
え～と、imageのpruneの説明書は・・・・

https://docs.docker.com/engine/reference/commandline/image_prune/

OPTIONつけろって？（付けない場合は、どうもTAGがないものだけが消えるようだ・・・）
```powershell:powershell
PS C:\> 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: ubuntu:xenial
untagged: ubuntu@sha256:20858ebbc96215d6c3c574f781133ebffdc7c18d98af4f294cc4c04871a6fe61
deleted: sha256:b6f50765242581c887ff1acc2511fa2d885c52d8fb3ac8c4bba131fd86567f2e
deleted: sha256:0214f4b057d78b44fd12702828152f67c0ce115f9346acc63acdf997cab7e7c8
deleted: sha256:1b9d0485372c5562fa614d5b35766f6c442539bcee9825a6e90d1158c3299a61
deleted: sha256:3c0f34be6eb98057c607b9080237cce0be0b86f52d51ba620dc018a3d421baea
deleted: sha256:be96a3f634de79f523f07c7e4e0216c28af45eb5776e7a6238a2392f71e01069
untagged: ubuntu:bionic
untagged: ubuntu@sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af
deleted: sha256:ad080923604aa54962e903125cd9a860605c111bc45afc7d491cd8c77dccc13b
deleted: sha256:95129a5fe07e89c1898dc40a027b291d5fe33a67b35a88f0f0eaf51ea691f0b5

Total reclaimed space: 198MB
```

なるほど・・・タグを消して、削除する流れなのか・・・

ひとまず、Imageに関しては取得と削除まで整理できたのでOK。