#22.プロセスについてChatGptと壁打ちした結果

# はじめに
※今回の記事の多くはChatGPTと壁打ちした内容になります。
　ところどころ明確な情報ではないのでご注意ください。
 
皆さん、Dockerでコンテナをビルドする際にDockerfileの`CMD`でサービスの立ち上げをする際に、よくフォアグラウンドで実行しないとコンテナが停止されるという記事を見ませんか。
実際、バックグラウンドで実行するとコンテナがうまく立ち上がらないといったことがあります。
では、なぜこのようなことが起きるのでしょうか。

# なんでコンテナが停止するのか？
通常のLinux環境ではsystemdやinitなどのプロセスマネージャーが導入されており、これらが子プロセスの管理を行ってくれています。なので、例えば、`php-fpm.service` を立ち上げる際は以下のように親プロセスである`systemd`からmaster processであるPID5705のphp-fpmを立ち上げてさらにfork()して子プロセス（PID5706以降）を作ります。
※PID5706以降についてはPPID(Parent Process ID)が5705となっていますね。
```
$ top
top - 20:09:29 up  4:36,  4 users,  load average: 0.03, 0.02, 0.00
Tasks: 175 total,   1 running, 103 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.2 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 s 
KiB Mem :  2027692 total,   292312 free,   477608 used,  1257772 buff/cache    
KiB Swap:        0 total,        0 free,        0 used.  1392012 avail Mem     

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND    
    1 root      20   0  123504   5600   4060 S   0.0  0.3   0:06.36 systemd    
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.03 kthreadd   
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0+ 


$ ps -eo pid,ppid,cmd | grep php-fpm | grep -v grep
 5705     1 php-fpm: master process (/etc/php-fpm.conf)
 5706  5705 php-fpm: pool www
 5707  5705 php-fpm: pool www
 5708  5705 php-fpm: pool www
 5709  5705 php-fpm: pool www
 5710  5705 php-fpm: pool www
 5711  5705 php-fpm: pool www
 5712  5705 php-fpm: pool www
 5713  5705 php-fpm: pool www
 5714  5705 php-fpm: pool www
 5715  5705 php-fpm: pool www
    
```

https://www.infra-linux.com/menu-linux6/parent-child-process/#google_vignette

https://wa3.i-3-i.info/word15037.html

という前段はここまでにして肝心のコンテナでの動作ですね。
コンテナをフォアグラウンドで実行した際のプロセスは以下のようになります。

```
$ docker exec -it {コンテナID/コンテナ名} /bin/bash

# ps -eo pid,ppid,comm
PID   PPID  COMMAND
    1     0 php-fpm
    6     1 php-fpm
    7     1 php-fpm
    8     1 php-fpm
    9     1 php-fpm
   10     1 php-fpm
   11     1 php-fpm
   12     1 php-fpm
   13     1 php-fpm
   14     1 php-fpm
   15     1 php-fpm
   37     0 bash
   60    37 ps
# ps
PID   USER     TIME  COMMAND
    1 root      0:19 php-fpm: master process (/usr/local/etc/php-fpm.conf)
    6 nginx     0:00 php-fpm: pool www
    7 nginx     0:00 php-fpm: pool www
    8 nginx     0:00 php-fpm: pool www
    9 nginx     0:00 php-fpm: pool www
   10 nginx     0:00 php-fpm: pool www
   11 nginx     0:00 php-fpm: pool www
   12 nginx     0:00 php-fpm: pool www
   13 nginx     0:00 php-fpm: pool www
   14 nginx     0:00 php-fpm: pool www
   15 nginx     0:00 php-fpm: pool www
   37 root      0:00 /bin/bash
   61 root      0:00 ps
```
PID1で固定化されてコンテナが停止することはございません。

現在
```
CMD ["/usr/local/sbin/php-fpm", "-F"]
```
バックグラウンドでの実行
```
CMD ["/usr/local/sbin/php-fpm"]
```

それでは実際にどのような処理が行われているかをChatGPTに聞いてみましょう。
※良い確認方法が思いつかなかったです。

# ChatGPTに聞いた結果
イメージ図で比較

🔸 通常 Linux（init あり）
```
[user bash (PID 1000)]
        |
    php-fpm (PID 1001)
        |
     fork()
        |
    master (PID 1002) ← 親が終了 → init (PID 1) が新しい親になる
```

🔸 コンテナ（init なし）
```
[Docker ENTRYPOINT] (PID 1)
        |
    php-fpm
        |
     fork()
        |
    master (PID ≠ 1) ← でも PID 1 終了 → Docker は「全体終了」とみなす
```
※本記事における「init」は、主にsystemdを指すものとします。

***通常 Linux（init あり）***
➀user bash(Linuxにおける実行コマンドなど）が任意のプロセスID（例では1000)で立ち上がる
➁別のPID（例では1001)のphp-fpmがfork()で子プロセスを作成
➂別のPIDのmaster processで立ち上がる
➃親（➁のphp-fpmのこと）が終了してPID1であるsystemdが親（親プロセスのこと）としてみなされる


***コンテナ（init なし）***
➀/usr/local/sbin/php-fpmがPID１になる
➁php-fpmがfork()で子プロセスを作成
➂別のPIDのmaster processで立ち上がる
➃PID１である➀が終了⇒PID1を見ているDockerはプロセス終了とみなしてコンテナを停止

# まとめ

この機会にプロセスに関する理解が深まり、とても良かったと思います。
Dockerは導入している企業も多く、汎用性も高い技術なのでプロセスとDockerコンテナの関連性はしっかり固めておきたいです。
最後までお読みいただき、ありがとうございました！