aws

【A-24】Docker commit, tar

Dockerイメージは複数のレイヤで構成されており、そのままでは単一ファイルとして扱うことができません。
そのため、コンテナの状態を保存・移動する際には commitexport/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
    • 別のマシンで .tarimport することで、同じ環境を復元。
    docker import ubuntu.tar my-imported-ubuntu
  • 環境のバックアップ
    • export を使うと、コンテナの状態を .tar に保存できるので、万が一のためにバックアップを取る用途に向いています。

docker commit export/importの違い

例えば、以下のような Dockerfile で作成されたコンテナがあるとします。

dockerfile
FROM ubuntu:latest
ENV MY_VAR="hello"
CMD ["bash"]

このコンテナを docker commit すると、環境変数 MY_VARCMD ["bash"] などのメタデータは 保持 されます。

docker run -it my-committed-image env

出力:

MY_VAR=hello

2. docker export/import はメタデータを失う

同じコンテナを export して import すると、環境変数や CMD が消えてしまう ことを確認できます。

sh
docker 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