Dockerで未使用オブジェクトを消す「prune」オプションの整理

# 概要

Docker で不要なものを消すガベージコレクション（garbage collection ）は、`prune` 系のオプションを使う。

`prune` 系オプションを使うと、使っていない Docker オブジェクト（コンテナ、イメージ、ネットワーク、ボリューム）をまとめて削除できる。コンテナが停止してからの時間を指定できる `--filter "until=24h"` の指定で、更に活用しやすくなる。あるいは ` --filter "until=2020-06-01"` のように、日時の指定も可能。

なお「prune」の意味とは、不要なものや余分なものを、削る、刈り取る、取り除くといったもの。

## 停止して24時間経過したコンテナと、使っていないイメージおよびネットワークを消す

```
$ docker system prune -a --filter "until=24h"
...
Are you sure you want to continue? [y/N]  ←ここで「y」+「Enter」を入力すると、処理進行
```



* `-a` は `--all` で、 build キャッシュと、中間イメージ（タグのないイメージ）も消す。開発環境では逆に影響が出るかも知れないので、場合によっては指定しないほうがパフォーマンスが上がる可能性
* `--filter "until=24h"` は、コンテナが停止して 24h = 24時間のものを削除。そして、それに紐付いて、未使用になったイメージ、未使用になったネットワークもまとめて削除してくれる。極端だが `until=1m` とすると、１分の指定になる。

なお、オプションには

* `-f` は `--force` で、 **確認プロンプト無しに、即座にまとめて削除するため、危険（利用するには何をしているのか理解が必要）なオプション** 。バッチ処理などで役立つのではないかと思うが、挙動を確認していない時は使わないほうが安全だろう。

```
docker system prune -a -f --filter "until=24h"
```

ちなみに、コンテナから使用されていない Docker ボリュームを消すには

```
docker system prune --volumes
```

強制( `-f`) オプションと組み合わせることも可能。


```
docker system prune --volumes -f
```

ちなみに、Docker ボリュームに対しては先ほどの `--filter` と `until` を組み合わせることができないので（オプションを指定してもエラー `Error response from daemon: Invalid filter 'until'` となり処理されない）、使っていないコンテナ、イメージ、ネットワーク、ボリュームを消したい場合は、次のコマンドを実行することになる。

```
docker system prune -a -f --filter "until=24h"
docker system prune --volumes -f
```

容量が空いたかどうかは、表示されるメッセージ `Total reclaimed space: XXX`　で確認するほかに、 `docker system df` でも確認できる。

```
$ docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              0                   0                   0B                  0B
Containers          0                   0                   0B                  0B
Local Volumes       0                   0                   0B                  0B
Build Cache         0                   0                   0B                  0B
```

----

以下、まとめてではなく、個々のオブジェクトに対する通常操作

## Docker コンテナの prune

```
docker container prune
```

停止しているコンテナ（ `docker ps -a` で見える残骸、 `docker rm で消すもの`）をまとめて削除するコマンドと。確認画面を出す必要がなければ `-f` か `--force` オプションを使う。

```
docker container prune -f
```

停止して24時間経過したものに、フィルタもできる

```
docker container prune -f --filter "until=24h"
```


他にも、日時の指定も可能。例えば、 2020年6月1日より前に止まったままのコンテナを削除するには

```
docker container prune --filter "until=2020-06-01"
```

## Docker イメージとコンテナの prune

```
docker image prune
```

```
docker network prune
```

これらは `docker continer prune` 系と同様のオプション指定が可能。


## Docker ボリュームだけ prune

```
$ docker volume prune
```

なおボリュームでは `--filter "until=24h"` のような `until` の組み合わせは利用できない。消したくないボリュームにラベルを付けておき、そのラベルがないボリュームを削除する運用が現実的か。

例 `prod` ラベルを持たないボリュームを削除

```
$ docker volume prune --filter "label!=prod"
```

## 全部まとめて prune（通常利用向け）

`docker system prune -a` を使うと、

* 停止中のコンテナ
* コンテナから使われていないネットワーク
* dangling イメージ（build 課程で生成される、タグが付いていないもの）
* build キャッシュ

これらをまとめて削除できる。

実行例：

```
$ docker system prune -a
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache

Are you sure you want to continue? [y/N] ←ここで「y」
```

（ `-a` は、コンテナに使われていないイメージを削除するオプション。もしイメージを残したければ、 `-a` は使わない）

```
$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N]
```

確認画面すら出したくない、あるいは出す必要がなければ `-f` オプションを付ける。


# 参考文章

* Prune unused Docker objects | Docker Documentation
  * https://docs.docker.com/config/pruning/
* docker container prune | Docker Documentation
  * https://docs.docker.com/engine/reference/commandline/container_prune/
* docker image prune | Docker Documentation
  * https://docs.docker.com/engine/reference/commandline/image_prune/