[Docker][備忘録] Docker Image関連のコマンドの使い方からDockerはどう使うのか雰囲気を知る備忘録

## 対象
- Dockerは使ってる、使ったことあるし、なんとなく環境も作ったり作らなかったりする
- やれと言われれば自分一人でもググったりしてなんとか立ち上げられるけど、説明してと言われると言葉に詰まる
- Dockerについてなんとなく図解することはできるけど、じゃあ実際にどういうコードを書けばいいのか説明にこまる
- 毎回コマンドをググる、ショートカットで対応しているけど根本的にはわからない
- (↑主に私です :sweat: )

## 環境
- MacOSX 10.15.3
- [docker desktop](https://www.docker.com/products/docker-desktop) 2.2.x

<img width="872" alt="Screen Shot 2020-03-13 at 15.20.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18705/ee8dfcfe-09d9-c2f8-bce2-067bb6abb037.png">


# まずDockerといっても何を使っているのかを知る

```zsh:command
$ docker version
```

```zsh:output
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:22:34 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea
  Built:            Wed Nov 13 07:29:19 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
```

ここでわかったのは、Docker Desktopをインストールして使っている際のDockerとは、Docker Engineという仕組みのことをいう様です。そしてDocker EngineにはClientとServerがある様です。
あと、containerはdaemonで動いているんですね（表現があいまいですみません）

# Dockerのコマンドにどんなものがあるか知る

Dockerコマンドは、要するにDocker Engineを操作する為のコマンドということです。

```zsh:command
$ docker --help
```

## dockerコマンドの基本的な型

```bash:output(excerpt)
Usage:	docker [OPTIONS] COMMAND
```

普通ですね。

### dockerコマンドのオプション
```output(excerpt)
Options:
      --config string      Location of client config files (default "/Users/watashi/.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 "/Users/watashi/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/Users/watashi/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/Users/watashi/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit
```

まだどう使うのかはわかりません。

### dockerコマンドで指定できる管理コマンド

```output(excerpt)
Management Commands:
  builder     Manage builds
  checkpoint  Manage checkpoints
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  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
```

なんとなく出てきました。
config, container, image, network, service, volume.... なんかDockerの勉強をしていて聞いたことがあるような単語たちですね。

ちなみにこれらはさらに `docker system --help` みたいな形で中を見ることができる様です。（--helpをつけなくても、同じ出力はみれます）

#### 例: docker systemコマンドの詳細

```zsh:command
$ docker system --help
```

```zsh:output
% docker system --help
Usage:	docker system COMMAND

Manage Docker

Commands:
  df          Show docker disk usage
  events      Get real time events from the server
  info        Display system-wide information
  prune       Remove unused data
```

`docker system prune` はつい最近使いましたが、`全ての停止中のコンテナ、ボリューム、ネットワーク、イメージを一括削除`するコマンドです。 `停止中` を `unused`、 `すべてのcontainer, volume, network, image` を `data` と表現しているんですね。
Dockerでは `prune` はこの様な意味を持って使われているようで、`docker system prune` 以外にも `docker images prune` なども出来る様です。


#### dockerコマンドで指定する操作コマンド（アクション・命令）

```output(excerpt)
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
  deploy      Deploy a new stack or update an existing stack
  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
```

build, exec, info, inspect, logs, pause, ps, rename, restart, rm, rmi, run, などなど、使った記憶があるものや、dockerでなくても他のコマンドと一緒に使ったことがある単語が登場しました。
基本的には、よく聞いた事があるようなコマンドたちですね。
めんどくさそうなのが、 `rm` は `container` を削除し、 `rmi` が `image` を削除するというところかなと思いました。


# Docker Imageの確認

## Docker imageを表示させるためのコマンド

[公式ドキュメントはこちら](https://docs.docker.com/engine/reference/commandline/image/)

```zsh:command
$ docker images --help
```

気をつけなくてはいけないのは、[`docker images`](https://docs.docker.com/engine/reference/commandline/images/) と [`docker image`](https://docs.docker.com/engine/reference/commandline/image/) は少し意味が違っています。

| Command | Command Domain | コマンドの意味 |
|:-----------------:|:------------------:|:------------------:|
| [docker images](https://docs.docker.com/engine/reference/commandline/images/) | docker | dockerが扱う操作コマンド |
| [docker image](https://docs.docker.com/engine/reference/commandline/image/)  | docker image | docker imageを扱う管理コマンド |

些細な意味の違いではありますが、このあたりが意識しておくのは大切かもしれません。


### 出力例
```zsh:output
REPOSITORY                                                               TAG                 IMAGE ID            CREATED             SIZE
${id}.dkr.ecr.${region}.amazonaws.com/${repositoryName}                  8                   b895764be967        11 hours ago        2.82GB
watashino/dockerImage                                                    latest              b3b481eaf996        11 hours ago        2.82GB
```

### 使い方
```zsh:usage
Usage:	docker images [OPTIONS] [REPOSITORY[:TAG]]
```

ポイントは、repositoryは `<repository_name>:<tag>` という表記も対応可能ということ。

```zsh:options
Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show numeric IDs
```
# Docker image の作成（ビルド）

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

## 使い方を確認

```zsh:command
$ docker build <path | url>
$ docker image build <path | url>
```

## docker-compose を使ったビルドについて

dockerを扱うとき、主にビルドするときでしょうか、よく [`docker compose`](https://docs.docker.com/compose/) という機能が利用されます。これは複数のコンテナを管理する為のツールで、 `docker-compose.yml` という名前の設定ファイルでよく扱われているかと思います。

### docker-compose を使ったビルド

```zsh:command
$ docker-compose build
```

下の様なdocker-composeファイルがあれば、 `Dockerfile`のパスとの関係性上適切なパスで上のコマンドを叩くことでビルドされます。
また、下のコマンドではビルドと起動を一緒に行う事もできます。

```zsh:command
$ docker-compose -up --build
```

```docker:docker-compose.yml
version: '3'
services:
  app:
    image: watashino/docker_image
    build:
      context: ..
      dockerfile: ./watashino/Dockerfile
    container_name: container_name
```

ちなみにこの docker-compose はバージョンによって対応している Docker Engine のバージョンが異なります。なので、Docker Engineのバージョンが古く、docker composeのバージョンが新しかったりすると、書き方的にエラーになったりもします。
[バージョンについてはこちら](https://docs.docker.com/compose/compose-file/)

# Docker image を削除

## 使い方を確認

```
$ docker image rm --help

Usage:	docker image rm [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Aliases:
  rm, rmi, remove

Options:
  -f, --force      Force removal of the image
      --no-prune   Do not delete untagged parents
```

### ポイント
- imageは複数指定できること。
- rmではなくrmi, remove などでも代用可能なこと
- `-f` で強制削除が可能なこと

## 使っていないimageを全部一括削除

```zsh:command
$ docker image prune
$ docker image rm $(docker images -q)
```

### ポイント

- `prune` は使われていないものを削除するといった意味を持っていましたが、ここでも同様でした
- `docker image rm $(docker images -q)` は `docker image rm` という操作コマンドの対象に `docker images -q` で出力される複数のimage idを指定しています

## 対象の image を削除

```zsh:command
$ docker image rm <image id>
$ docker rmi <image id>
```

どちらでも大丈夫でした。
ここで最初にわかんなかったのが、 `対象の指定の仕方は image id` ということです。repositoryではありません。
`$ docker images` を叩くと、何がrepositoryで何がimage idなのかわかります。



# 一旦終わりに

docker の image に関するコマンドについての備忘録でしたが、分かっている人からしたら当たり前なことかと思います。
でもよく分かっていない人からすると、整理するのに少し役立つかもしれません。


*なお、この記事は備忘録になります。自分一人で調べてもわかんないけど、だれかと一緒にやるとぱっと解決策を見つけられたりもしたので、そういう意味も込めてこの記事を残しています。*