プログラミング初心者がアーキテクトっぽく語る

見苦しい記事も多数あるとは思いますが訂正しつつブログと共に成長していければと思います

「docker run -it」にするとコンテナがすぐに終了しない理由

Dockerを使ったことがある人ならこんなことを経験したことがあるかもしれない。

このように実行するとコンテナがすぐに終了してまう。

docker run ubuntu:latest

このように「-it」を付けて実行するとコンテナは終了しない。

docker run -it ubuntu:latest

そしてそれ以降、おまじないように「-it」をつけていないだろうか?

しかし「-it」がなくてもすぐに終了しないコンテナもある。

今回はコンテナをすぐに終了させないために「-it」がなぜ有効なのか、なぜ「-it」が不要なコンテナもあるのか整理しよう。


コンテナが終了する条件

仮想マシンはOSを実行することが目的だ。よってOSがShutdownされると仮想マシンも停止する。

コンテナはプロセスを実行することを目的だ。よってRoot Processと呼ばれるプロセスが終了するとコンテナも終了する。


Root Process

Root Processはコンテナ上で最初に実行されるプロセスのことだ。コンテナ内でのPIDは1になる。

Root Processになるのはdockerfileの中でENTRYPOINTやCMDで指定されたコマンドだ。

CMDで指定されたコマンドはdocker runコマンドで上書きできる。


ubuntuコンテナのRoot Process

先程例にあげたubuntuコンテナのRoot Processを調査してみよう。

ubuntuイメージのdockerfileを覗くと一番下に以下のように記述されている。

CMD ["/bin/bash"]

ubuntuコンテナのRoot Processはbashであることがわかる。bashが終了すればコンテナも終了する。


bash

次にbashが終了する条件を調べてみよう。

bashは実行開始するとterminalからの入力を待つ。exitと入力されると終了する。

実行開始時にterminalが見つからない場合は終了する。


「-it」オプション

最後に「-it」オプションについて調べてみよう。

-iは標準入力をAttachする。

-tはTerminalをAttachする。

「-t」は「-i」とセットで「-it」として利用するのが一般的だ。

下記のように「-t」なしで実行するとterminalがコンテナにAttachされない。bashはterminalがないのですぐに終了する。Root Processが終了したのでコンテナもすぐに終了する。

docker run ubuntu:latest

「-t」を付けて実行するとterminalがコンテナはAttachされる。bashはterminalがあるので入力を待つ。Root Processが終了しないのでコンテナも終了しない。

docker run -it ubuntu:latest

結論

Root Processがシェルだった場合はdocker runに「-it」をつけないとRoot Processがすぐに終了してコンテナが終了する。

Root Processがシェルでなかった場合(nginx等)は「-it」をつけてもコンテナの生死に影響しない。