Chapter 08

2部: コンテナの状態保持

ほげさん
ほげさん
2022.03.21に更新

コンテナを削除するとコンテナで行った操作がどうなるか学び、Dockerfile やボリュームなどが必要になる理由を理解しましょう。

コンテナの状態について

【 2部: Docker を理解するためのポイント 】で次の特徴を挙げました。

  1. 複数のコンテナは互いに独立していて影響できず、独自に動作する

image

このページではこの特徴を2つの観点から確認します。

  1. 同じイメージから起動しても違うコンテナである
  2. コンテナでの操作はほかのコンテナに影響しない

同じイメージから起動しても違うコンテナである

これは CONTAINER ID を確認すれば明らかです。

1つめの Nginx コンテナをデフォルト命令 ( nginx ) で起動します。

Host Machine
$ docker container run \
    --name nginx1      \
    --rm               \
    --detach           \
    nginx:1.21

2つめの Nginx コンテナをデフォルト命令 ( nginx ) で起動します。

Host Machine
$ docker container run \
    --name nginx2      \
    --rm               \
    --detach           \
    nginx:1.21

コンテナ一覧を確認すると、CONTAINER ID の異なる2つのコンテナが起動していることが確認できます。

Host Machine
$ docker container ls

CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
770f08892af6   nginx:1.21     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   80/tcp    nginx2
abff10020aa4   nginx:1.21     "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   80/tcp    nginx1

nginx1 コンテナを削除して再度 nginx1 という名前でコンテナを起動します。

Host Machine
$ docker container stop \
    nginx1
    
$ docker container run \
    --name nginx1      \
    --rm               \
    --detach           \
    nginx:1.21

名前は同じですが、先ほどとは CONTAINER ID が違うのでさらに別のコンテナです。

Host Machine
$ docker container ls

CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
4f37cff849da   nginx:1.21     "/docker-entrypoint.…"   5 seconds ago   Up 5 seconds   80/tcp    nginx1
770f08892af6   nginx:1.21     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   80/tcp    nginx2

同じイメージから起動しても、同じ名前で起動しても、コンテナは起動するたびに新しい別物 だということが確認できました。

image

コンテナでの操作はほかのコンテナに影響しない

こちらも試してみれば明らかです。

1つめの Ubuntu コンテナをデフォルト命令 ( bash ) で起動します。

Host Machine
$ docker container run \
    --name ubuntu1     \
    --rm               \
    --interactive      \
    --tty              \
    ubuntu:20.04

#

2つめの Ubuntu コンテナをデフォルト命令 ( bash ) で起動します。

Host Machine
$ docker container run \
    --name ubuntu2     \
    --rm               \
    --interactive      \
    --tty              \
    ubuntu:20.04

#

ubuntu1 コンテナの方で vi をインストールして、~/hello.txt を作成します。

Container ( ubuntu1 )
# apt update
# apt install -y vim

# vi ~/hello.txt
( hello world と入力して :wq で保存して終了する )

次に ubuntu2 コンテナで vi コマンドを実行すると、ubuntu2 コンテナには vi が存在しないことが確認できます。

Container ( ubuntu2 )
# vi

bash: vi: command not found

さらに ~/hello.txt も存在しません。

Container ( ubuntu2 )
# cat ~/hello.txt

cat: ~/hello.txt: No such file or directory

コンテナでの操作や作成したファイルはほかのコンテナには影響しない ことが確認できました。

image

コンテナの状態変更を別のコンテナに反映するには

大別して 2 つ方法があります。

  • 構成変更を全コンテナに反映したいならイメージを作る
  • コンテナのファイルを残したいならホストマシンと共有する

どちらもページを設け細かく説明するので、ここでは紹介だけします。

構成変更を引き継ぎたいならイメージを作る

vi をどのコンテナでも使いたい場合は「Dockerfile で vi 入りイメージを作っておく」ことで解決できます。

image

そうすれば「コンテナを起動するたびに vi を入れる」のではなく「vi が入ったコンテナを起動する」ことができます。

詳しくは【 2部: Dockerfile の基礎 】で説明します。

ファイルを残したいならホストマシンと共有する

~/hello.txt のファイルが消えてほしくない場合は「ホストマシンにファイルを共有する」ことで解決できます。

image

そうすれば「コンテナを起動するたびにファイルを作る」のではなく「コンテナを起動してからホストマシンのファイルを使う」ことができます。

詳しくは【 3部: ボリューム 】と【 3部: バインドマウント 】で説明します。

まとめ

簡潔にまとめます。

  • コンテナは 起動するたびに違うコンテナ である
  • コンテナの操作は ほかのコンテナに影響しない
  • 別のコンテナに変更を反映するには、なんらかの対処が必要
    • Dockerfile
    • ボリュームやバインドマウント

混乱してしまったときは立ち返ってみてください。

このページで作成したものの掃除

Host Machine
$ docker container rm --force \
    nginx1 nginx2 ubuntu1 ubuntu2