Dockerイメージは複数のレイヤで構成されており、そのままでは単一ファイルとして扱うことができません。
そのため、コンテナの状態を保存・移動する際には commit
や export/import
を活用 する必要があります。
[ 学習フェーズ ]
docker commit
の役割とユースケース
役割
docker commit
は コンテナの変更を新しいイメージとして保存します。- コンテナの状態をスナップショットとして記録 し、後で同じ環境を再現できます。
ユースケース
- テスト環境の保存
docker run
でコンテナを起動し、必要なソフトウェアを追加した後、その状態を保存。- 例:
ubuntu
コンテナにvi
をインストールし、その状態をcommit
で保存。
docker commit my-ubuntu ubuntu-with-vi
- 次回から
ubuntu-with-vi
を使えば、vi
をインストールする手間が省けます。
- デバッグ用のスナップショット
- アプリケーションをコンテナで動かしながらデバッグし、特定の状態を保存する。
- 例: Webアプリをデバッグ中に
commit
でスナップショットを作成し、後で再現可能にする。
docker export/import
の役割とユースケース
役割
docker export
は コンテナのファイルシステムを.tar
ファイルとしてエクスポート し、import
で別の環境に復元できます。- Dockerのレイヤ構造を保持せず、シンプルな単一の
.tar
ファイルに変換する ため、移動やバックアップが容易です。
ユースケース
- コンテナ環境を別のマシンに移動
commit
で作成したイメージは 複数のレイヤに分かれる ため、そのまま移動するとレイヤ情報を維持する必要があります。export
を使うと、コンテナの状態を単一の.tar
ファイル にできるため、簡単に転送でき
ます。
docker export my-ubuntu -o ubuntu.tar
- 別のマシンで
.tar
をimport
することで、同じ環境を復元。
docker import ubuntu.tar my-imported-ubuntu
- 環境のバックアップ
export
を使うと、コンテナの状態を.tar
に保存できるので、万が一のためにバックアップを取る用途に向いています。
docker commit
とexport/import
の違い
例えば、以下のような Dockerfile で作成されたコンテナがあるとします。
dockerfileFROM ubuntu:latest
ENV MY_VAR="hello"
CMD ["bash"]
このコンテナを docker commit
すると、環境変数 MY_VAR
や CMD ["bash"]
などのメタデータは 保持 されます。
docker run -it my-committed-image env
出力:
MY_VAR=hello
2. docker export/import
はメタデータを失う
同じコンテナを export
して import
すると、環境変数や CMD が消えてしまう ことを確認できます。
shdocker export my-container -o my-container.tar
docker import my-container.tar my-imported-image
docker run -it my-imported-image env
出力:
# `MY_VAR` が消えている
どう対処すればいいのか?
docker export/import
ではメタデータが失われるため、docker run
時に環境変数やエントリーポイントを手動で指定する 必要があります。
docker run -it --entrypoint /bin/bash -e MY_VAR="hello" my-imported-image
+α save/load
メタデータも保持したいなら、export/import
ではなく save/load
という方法もあります。
自身で利用方法や違いを調べてみましょう。
[ 実践フェーズ ]
ハンズオン: commit
, export
, import
を使ったコンテナの保存と移動
Ubuntuコンテナを起動し、vi
をインストール
docker run -it --name my-ubuntu ubuntu:latest bash
コンテナ内で以下のコマンドを実行し、vi
をインストール:
apt update && apt install -y vi
exit
docker commit
でイメージを作成
コンテナの変更を新しいイメージとして保存:
docker commit my-ubuntu ubuntu-with-vi
保存されたイメージを確認:
docker images
確認ポイント:
ubuntu-with-vi
という名前のイメージが作成されているか?
docker export
で .tar
ファイルとして保存
コンテナを .tar
に変換:
docker export my-ubuntu -o ubuntu.tar
エクスポートされたファイルを確認:
ls -lh ubuntu.tar
確認ポイント:
ubuntu.tar
が作成されているか?.tar
は単一ファイルであることを確認。
docker import
で .tar
から新しいイメージを作成
docker import ubuntu.tar my-imported-ubuntu
イメージ一覧を確認:
docker images
確認ポイント:
my-imported-ubuntu
という新しいイメージが作成されているか?
my-imported-ubuntu
からコンテナを起動し、vi
の存在を確認
docker run -it my-imported-ubuntu bash
コンテナ内で vi
があるか確認:
which vi
確認ポイント:
which vi
の出力が空なら、export/import
ではvi
の変更が反映されなかった(パッケージのメタデータが失われる)。commit
したubuntu-with-vi
ではvi
が維持される(export/import
の違いを理解)。
6. 片付け(不要なコンテナとイメージを削除)
docker stop my-ubuntu
docker rm my-ubuntu
docker rmi ubuntu-with-vi my-imported-ubuntu
rm ubuntu.tar