docker run で動かしたプロセスの停止方法

どうも、EOA（@fukamiAO）です。

[前回の記事](https://qiita.com/fukamiAO/items/9ce0f9ec168a314c1c88)で、Docker Community Edition for Macをインストールしてから色々と試そうとした中で疑問に感じたことを書きたいと思います。

#先ずはdocker runについて
Dockerを入れたら何はともあれ、このコマンドからスタートすると思います。
構文や使用可能なオプションについては、"docker run --help"や、以下の公式ドキュメントでご確認ください。

- [公式ドキュメント（英語）](https://docs.docker.com/engine/reference/run/)
- [日本語ドキュメント（17.06.Beta）](http://docs.docker.jp/engine/reference/run.html)

実行してみると以下のような感じ。

- Ubuntu

```bash
# Ubuntuイメージを起動
eoa$ docker run -i -t ubuntu /bin/bash

# 色々とPullしてきて...

# Ubuntuイメージが無事に立ち上がった
Status: Downloaded newer image for ubuntu:latest
root@6161b9786670:/#
```

- nginx

```bash
# nginxイメージを起動
eoa$ docker run -p 8080:80 nginx

# バックグラウンド実行（ &）していないため、何も表示されないが、
# ブラウザ上で、http://$(docker-machine ip):8080/　へアクセスするとnginxのウェルカムページが開く
# 注) $(docker-machine ip)の部分は、実際にコマンド打って各自確かめたIPアドレスに置き換えてください
```

# で、本題です
上記の通り、docker runコマンドを使うと簡単に各イメージのプロセスが立ち上がるまでは分かったんだけど、「へぇ〜」と思って終了させようとしたときに、ふと気になったんです。

**え？操作方法違うん？**

何かと申しますと、Ubuntu側は[control + D]を入力すると、ターミナル上で「exit」コマンドが実行されて、プロセスが終了する感じ。

- Ubuntuだと、こんなん。

```bash
# 起動された Ubuntuイメージの中で、[control + D]
# すると、exitコマンドに勝手に変換されて、
root@xxxxxxxxxxxx:/# exit

# docker runする前の自分のターミナルに！！
eoa$ 
```

で、nginx側も一緒（[control + D]でサーバ止まるん）だろうと思って試すと違った。

- nginxだと、こんなん。

```bash
# nginxが起動している時に、
eoa$ docker run -p 8080:80 nginx

# [control + D]を打っても以下が表示されるだけで、サーバは止まらない！！
^D

# ちなみにこっちは[control + C]で止まった。
^C eoa$ 
```

# 色々と調べてみると
と書いたものの、色々調べるまでもなかった。。。

- [Ctrl+dでexitとかやらなくて良かったことを今更知った・・・ | NormalBlog.net](https://normalblog.net/system/ctrl-d/)

つまりは、[control + D]はdocker runを止めるコマンドではなくて、Shellから抜けるためのコマンドだったと。
で、よくよく考えると、nginxに限らず、Webサーバ（Tomcatとかもそうだったはず）をフォアグラウンドで（ &付けずに）動かしていた場合、よく[Control + C]で止めていたな、と。
結局、docker以前にShellとかWebサーバ一般の動かし方が分かってなかっただけかよorz

# で、もう一度本題です
「結局、docker run してるプロセスって一律で止める方法ないん？」ってなりまして。
[学習中の書籍](https://book.mynavi.jp/ec/products/detail/id=53069)や、ネット上で文献漁って一番確実だなと思った方法は以下の通り。

1. "docker ps -a"コマンドで（停止しているものも含めて）残存しているコンテナをすべて確認。
2. 確認したCONTAINER IDを使って、コンテナを操作。
 1. 起動している（STATUSが"Up [期間]"と出ているもの）を停止したいだけの場合："docker kill [確認したCONTAINER ID]"
 2. 停止している（STATUSが"Exited [期間]"と出ているもの）を削除したい場合："docker rm [確認したCONTAINER ID]"

注) CONTAINER IDの部分はNAMES（任意で付けられる一意のコンテナ名）が指定されていれば、そちらでも可らしいです。
　  一連の動作をサクッと確認しておきましょう。

```bash
# 最初に停止中も含めた全てのプロセスを確認（各項目のヘッダのみで、プロセスは何も表示されない）
eoa$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

# バックグラウンドで、Ubuntuを動かしてみます
eoa$ docker run -i -t ubuntu /bin/bash &
[2] 13422

# 同様にバックグラウンドで、nginxを動かしてみます
# （なお、今回は"--name"オプションを使って、コンテナに「web-server」という名前を付けています）
eoa$ docker run -p 8080:80 --name web-server nginx &
[3] 13428

# 起動中のプロセスのみを確認します（docker psコマンドから、-aオプションを外すだけです）
# -> あれ？ Ubuntuは？？
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMES
c7170e9b8b03        nginx               "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   web-server

# すべてのプロセスを確認します
# -> Ubuntuいたぁ！！ けど、StatusがUpになっていません。
# これについては、また別の機会にみてみたいと思います。
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
c7170e9b8b03        nginx               "nginx -g 'daemon of…"   2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   web-server
167a4eddb568        ubuntu              "/bin/bash"              4 minutes ago       Created                                    xenodochial_poitras

# とりあえず、動いている（STATUSがUpになっている）nginxを止めてみたいと思います。
# ここではCONTAINER IDを用いてみます。
eoa$ docker kill c7170e9b8b03
c7170e9b8b03
[3]   Exit 137                docker run -p 8080:80 --name web-server nginx

# 再度プロセスを確認します。nginxが止まっている（STATUSがExitedになっている）のが分かります。
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
c7170e9b8b03        nginx               "nginx -g 'daemon of…"   2 minutes ago       Exited (137) 53 seconds ago                       web-server
167a4eddb568        ubuntu              "/bin/bash"              4 minutes ago       Created                                           xenodochial_poitras

# 次に止めたばかりのnginxプロセスを削除します。
# 今度はせっかく付けたので、NAMESのweb-serverを指定して削除してみます。
$ docker rm web-server
web-server

# プロセスを確認します。nginxプロセスがどこにも見当たらず、削除されていることが分かります。
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
167a4eddb568        ubuntu              "/bin/bash"         6 minutes ago       Created                                 xenodochial_poitras

# 最後にUbuntuも止めてみます。
# こちらはNAMESを付けた覚えはないのですが、「xenodochial_poitras」という名前がついています。
# （デフォルトで付けてくれるのかな？？）何はともあれ、この名前を使用してみます。
$ docker rm xenodochial_poitras
xenodochial_poitras

# プロセスを確認します。どうやら無事に消えた様です。
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

一応、起動有無を確認せずに全てのコンテナを削除したい場合には、"docker rm -f $(docker ps -a -q)"という**一撃必殺技**も存在する様ですが、実際の業務ではこんな恐怖のコマンドを打ち込む人はいないと思います。「間違えた」では済まされませんもんね。

#最後に
今回は、"docker run"でイメージ起動してみたことと、その停止方法についての疑問点・検証・調べた内容を備忘録程度に書き連ねました。
分かったこととして、

- "docker run"で起動したプロセスは、"docker kill"で停止でき、"docker rm"で削除できるということ

が挙げられる一方で、新たに次の様な疑問点も挙がって来ました。

- ネット調べてると、プロセスの起動と停止は"docker start"や"docker stop"でやっている人もいる。"docker run"や"docker kill"とどう違うんだろう？
- バックグラウンドでUbuntuを起動した際に出たSTATUS「Created」って、どういう状態なんだろう？
- 結局、"docker ps"と"docker ps -a"とで、どの様な出力結果の差が出ているの？

等々。これらはまた、別の機会に。

Docker超初心者（その他も大概）ゆえ、的外れなことも書いているかもしれません。
「もっと良いやり方あるよ〜」とか、「そこ違ってるよ〜」っていうご指摘・ご意見をお持ちの方がいれば、是非コメントで教えてくださいね。

ではまた。お疲れ様でした。