【Docker】stop/startとpause/unpauseの違い

## Bingチャットに聞いてみた

まず、4つのコマンドのリファレンスURLと簡単な説明を聞いてみました。

>1. `docker pause`
>    - リファレンスURL: [こちら](https://docs.docker.jp/engine/reference/commandline/pause.html)
>    - `docker pause`コマンドは、指定したコンテナ内のすべてのプロセスを一時停止します。
>
>1. `docker unpause`
>    - リファレンスURL: [こちら](https://docs.docker.jp/v1.11/engine/reference/commandline/unpause.html)
>    - `docker unpause`コマンドは、一時停止されたコンテナ内のすべてのプロセスを再開します。
>
>1. `docker stop`
>    - リファレンスURL: [こちら](https://docs.docker.jp/engine/reference/commandline/stop.html)
>    - `docker stop`コマンドは、コンテナ内のメインプロセスにSIGTERM（終了信号）を送り、必要であればSIGKILL（強制終了信号）を送ります。
>
>1. `docker start`
>    - リファレンスURL: [こちら](https://docs.docker.jp/v1.9/engine/reference/commandline/start.html)
>    - `docker start`コマンドは、停止したコンテナを再起動します。

続いて、`docker pause/unpause`と`docker stop/start`の違いについて聞いてみました。

>`docker pause/unpause`と`docker stop/start`の違いは、コンテナのプロセスに対する影響にあります。
>
>～中略～
>
>したがって、`docker pause/unpause`はプロセスを一時停止し再開するのに対し、`docker stop/start`はプロセスを終了し再起動します。

## 試してみた
今回は[Docker Playground](https://labs.play-with-docker.com/)の環境を使いました。DockerHubのアカウントがあれば無償で色々試せる環境です。
バージョン情報などは以下、

<!-- open属性なし -->
<details><summary>docker versionコマンドの結果</summary>

```
[node1] (local) root@192.168.0.28 ~
$ docker version
Client:
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        afdd53b
 Built:             Thu Oct 26 09:04:00 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:05:28 2023
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.7.6
  GitCommit:        091922f03c2762540fd057fba91260237ff86acb
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfc
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```
</details>

### 検証用のプログラム
起動時に日付を`date_output.txt`に書き込み、標準出力にdate結果を表示し続けるコンテナを作ってみました。

```loop_date.bash
#!/bin/bash

# ファイル名を指定します
FILE="date_output.txt"

# dateコマンドの出力をファイルに追記します
date > $FILE

# 無限ループを作成します
while true
do
    # dateコマンドの標準出力に出力します
    date
    # 10秒間スリープします
    sleep 10
done
```

Dockerfileは以下です。ベースのイメージにはUbuntuを使用しています。
```Dockerfile
# Ubuntuイメージをベースにする
FROM ubuntu:latest

# ローカルのスクリプトファイルをコンテナにコピーする
COPY loop_date.bash /loop_date.bash

# スクリプトに実行権限を付与する
RUN chmod +x /loop_date.bash

# コンテナが起動したときにスクリプトを実行する
CMD ["/loop_date.bash"]
```

以下コマンドで`ubuntu_loop`という名前で、イメージをビルドしています。
```
docker build -t ubuntu_loop .
```

### docker pauseとunpaseを試してみる

`docker run`で`c1`という名称でコンテナを起動します。`date_output.txt`の日付を確認すると、コンテナを起動した日付が入っています。
```
[node1] (local) root@192.168.0.28 ~
$ date; docker run -dit --name c1 ubuntu_loop
Sun May 19 07:01:09 UTC 2024
acc4cf0a6bb9b25c1e1b773ed34c6e9f67dbfe45e126683eddffc69897b27940
[node1] (local) root@192.168.0.28 ~
$ docker exec c1 cat /date_output.txt
Sun May 19 07:01:10 UTC 2024
[node1] (local) root@192.168.0.28 ~
$ docker logs c1
Sun May 19 07:01:10 UTC 2024
Sun May 19 07:01:20 UTC 2024
```

`docker pause`コマンドでコンテナをPause状態にします。
```
[node1] (local) root@192.168.0.28 ~
$ date; docker pause c1; docker container ls -a
Sun May 19 07:01:33 UTC 2024
c1
CONTAINER ID   IMAGE         COMMAND             CREATED          STATUS             
      PORTS     NAMES
acc4cf0a6bb9   ubuntu_loop   "/loop_date.bash"   24 seconds ago   Up 22 seconds (Paused)             c1
```

60秒ほど待ってから、`docker unpase`コマンドでコンテナを再開します。
`date_output.txt`の中身は変わっていません。
```
[node1] (local) root@192.168.0.28 ~
$ date; docker unpause c1; docker container ls -a
Sun May 19 07:02:52 UTC 2024
c1
CONTAINER ID   IMAGE         COMMAND             CREATED              STATUS              PORTS     NAMES
acc4cf0a6bb9   ubuntu_loop   "/loop_date.bash"   About a minute ago   Up About a minute             c1
[node1] (local) root@192.168.0.28 ~
$ docker exec c1 cat /date_output.txt
Sun May 19 07:01:10 UTC 2024
[node1] (local) root@192.168.0.28 ~
$ docker logs c1
Sun May 19 07:01:10 UTC 2024
Sun May 19 07:01:20 UTC 2024
Sun May 19 07:01:30 UTC 2024
Sun May 19 07:02:52 UTC 2024
Sun May 19 07:03:02 UTC 2024

```

### docker stopとstartを試してみる

先ほどと同様にコンテナを起動します。コンテナ名は`c2`とします。
```
[node1] (local) root@192.168.0.28 ~
$ date; docker run -dit --name c2 ubuntu_loop
Sun May 19 07:04:25 UTC 2024
bc64d059a595730469907f1bcafbd855dc9d1e08d91fa9c1f7e8483f88562cbb
[node1] (local) root@192.168.0.28 ~
$ docker exec c2 cat /date_output.txt
Sun May 19 07:04:27 UTC 2024
[node1] (local) root@192.168.0.28 ~
$ docker logs c2
Sun May 19 07:04:27 UTC 2024
Sun May 19 07:04:37 UTC 2024
```

`docker stop`コマンドでコンテナを停止状態にします。
```
[node1] (local) root@192.168.0.28 ~
$ date; docker stop c2; docker container ls -a
Sun May 19 07:05:01 UTC 2024
c2
CONTAINER ID   IMAGE         COMMAND             CREATED          STATUS                                PORTS     NAMES
bc64d059a595   ubuntu_loop   "/loop_date.bash"   47 seconds ago   Exited (137) Less than a second ago             c2
acc4cf0a6bb9   ubuntu_loop   "/loop_date.bash"   4 minutes ago    Up 4 minutes                                    c1
```

こちらも60秒ほど待ってから、`docker start`コマンドでコンテナを再開します。
先ほどとの違いとして、`date_output.txt`の日付が`docker start`コマンドを実行した日付に置き換わっています。
```
$ date; docker start c2; docker container ls -a
Sun May 19 07:06:31 UTC 2024
c2
CONTAINER ID   IMAGE         COMMAND             CREATED         STATUS                  PORTS     NAMES
bc64d059a595   ubuntu_loop   "/loop_date.bash"   2 minutes ago   Up Less than a second             c2
acc4cf0a6bb9   ubuntu_loop   "/loop_date.bash"   5 minutes ago   Up 5 minutes                      c1
[node1] (local) root@192.168.0.28 ~
$ docker exec c2 cat /date_output.txt
Sun May 19 07:06:32 UTC 2024
[node1] (local) root@192.168.0.28 ~
$ docker logs c2
Sun May 19 07:04:27 UTC 2024
Sun May 19 07:04:37 UTC 2024
Sun May 19 07:04:47 UTC 2024
Sun May 19 07:04:57 UTC 2024
Sun May 19 07:05:07 UTC 2024
Sun May 19 07:06:32 UTC 2024
Sun May 19 07:06:42 UTC 2024
```

このことから、
+ `docker pause/unpause`はプロセスの一時停止/再開
+ `docker stop/start`はプロセスの再起動
という点を確認することができました。