docker-compose down はなぜコンテナを削除するのか

DockerでRailsの開発環境を構築しました. 公式ドキュメントを見てみると, プロジェクトの停止にはdocker-compose downを使えと書いてあります. このコマンドを実行するとコンテナが削除されますが, どうしてコンテナを削除する必要があるのでしょうか. 実験を通して考察していきます.

実験

コンテナをわざわざ消去するということは, 以下の2つに明確な差があるということです.

  • コンテナを作り直して起動する.
  • 停止したコンテナを再起動する.

ここで思い出すのが, DockerfileにおけるCMD命令ですね. これはコンテナを起動する際に発動させるコマンドを指定するものです. ではこれにフォーカスして実験してみましょう.

Dockerfileを作成します.

FROM debian
CMD echo "Hello, World."

イメージをビルドします. イメージ名はhelloにしましょう.

$ docker build -t hello .

コンテナを起動します.

$ docker run hello
Hello, World.

Dockerfile内で指定した通りのコマンドが実行されましたね. 現在のコンテナの状況を見てみましょう.

$ docker ps -a
CONTAINER ID   IMAGE   COMMAND                   CREATED       STATUS
bce34cc95f4e   hello   "/bin/sh -c 'echo \"H…"   8 second ago  Exited (0) 26 seconds ago

STATUSExitedになっています. つまりコンテナが停止していますね. echoというプロセスが終了したために, コンテナもそれに合わせて停止してしまったのです.

この状態からコンテナを再起動してみましょう.

$ docker start bce34
bce34

コンテナIDを返しただけで, echoは実行されませんでした.

考察

上の実験からわかることは, CMD命令で指定されたコマンドは, コンテナを構築し, 起動したときに発動するということです. Dockerfile内のCMD命令について, 公式ドキュメントにはこう書かれていました.

the CMD instruction sets the command to be executed when running the image

日本語訳しましょう.

CMD命令は, イメージを起動する際に実行されるコマンドを設定する

コマンドが実行されるのは, イメージの起動時だったわけです.

結論

コンテナを起動させるたびに, 指定したコマンドも同時に実行したいから, 毎回コンテナを削除していたのでした. Railsの環境を構築した際は, イメージ起動時のコマンドとしてRails serverの起動が指定されていました. コンテナを削除してくれていたおかげで, Rails serverも自動的に起動するようになっていたわけです.