dockerのコンテナとイメージの違い

もうほぼ6年前ですが、stack overflowにdockerのコンテナとイメージの違いを詳細に説明してくださるすごい人がいたので、自分用にまとめようと思います。

In Docker, what’s the difference between a container and an image?

そちらに書いてあった文章です。

Images are frozen immutable snapshots of live containers.
Containers are running (or stopped) instances of some image.

要するにイメージはコンテナのスナップショットで、コンテナは走らせているイメージのインスタンス、ということになるのでしょうか。

以下の画像のようにdockerのイメージをdockerfileから組み立てて、そのイメージを走らせるとコンテナになると。

例えば以下からubuntuという名前のdocker imageを立ち上げてfooというファイルを作るとします。

$ docker run -i -t ubuntu  /bin/bash
root@48cff2e9be75:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@48cff2e9be75:/# cat > foo
This is a really important file!!!!
root@48cff2e9be75:/# exit

ここでexitするともちろんイメージはスナップショットなのでもちろんfooファイルはubuntuから消えます。

以下のようにもう一回イメージを起動してlsコマンドを使うと初期状態から変化していないことがわかります。

$ docker run -i -t ubuntu  /bin/bash
root@abf181be4379:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@abf181be4379:/# exit

しかしイメージをもとに作られたコンテナはそのファイルをまだ保持しており、コミットして新たなイメージとして保存することが可能です。

docker ps -aで確認することができます。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED              STATUS                          PORTS                      NAMES
abf181be4379        ubuntu:14.04        /bin/bash              17 seconds ago       Exited (0) 12 seconds ago                                  elegant_ardinghelli    
48cff2e9be75        ubuntu:14.04        /bin/bash              About a minute ago   Exited (0) 50 seconds ago                                  determined_pare        
...

こちらをcommitすれば、新たなイメージとして保存できます。

$ docker commit 48cff2e9be75 ubuntu-foo
d0e4ae9a911d0243e95556e229c8e0873b623eeed4c7816268db090dfdd149c2

こちらのイメージを立ち上げるとたしかに先程作ったファイルは残っています!

$ docker run ubuntu-foo /bin/cat foo
This is a really important file!!!!

最後に

dockerについて筆者はなんとなくgitに似ているなと感じました。

また、imageとcontainerという2つの状態ででループを描いている感じで視覚化されてよかったという感想です。