はじめに
この実験では、docker buildx debug build コマンドを効果的に使用して Docker イメージをビルドおよび検査する方法を学びます。まず、Dockerfile を使用してデフォルト設定でシンプルなイメージをビルドすることから始めます。
基礎を踏まえた上で、より高度なビルドシナリオを探求します。これには、ビルド引数(build arguments)やラベルをイメージに組み込む方法が含まれます。また、ビルドプロセス中に特定のプラットフォームをターゲットにしたり、結果のイメージをファイルに出力する方法も学びます。最後に、この実験ではビルドキャッシュを制御する技術や、ビルド中にシークレットを安全に公開する方法についてもカバーし、docker buildx debug build コマンドの機能を包括的に理解できるようにします。
デフォルト設定でシンプルなイメージを構築
このステップでは、Dockerfile を使用してシンプルな Docker イメージをビルドする方法を学びます。Dockerfile は、イメージを構築するためにコマンドラインで実行可能なすべてのコマンドを含むテキストドキュメントです。Docker は Dockerfile から命令を読み取り、自動的にイメージをビルドできます。
まず、この実験の作業ディレクトリである ~/project ディレクトリに移動します。
cd ~/project
次に、シンプルな Dockerfile を作成します。~/project ディレクトリに Dockerfile という名前のファイルを作成します。この Dockerfile は、ubuntu ベースイメージを基に cowsay パッケージをインストールする手順を定義します。
nano エディタを使用して Dockerfile を作成・編集します:
nano Dockerfile
Dockerfile に以下の内容を追加します:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "Hello, Docker!"]
この Dockerfile の内容を分解してみましょう:
FROM ubuntu:latest: この命令は新しいイメージのベースイメージを指定します。Docker Hub の公式 Ubuntu イメージの最新バージョンを使用しています。RUN apt-get update && apt-get install -y cowsay: この命令は現在のイメージの上に新しいレイヤーでコマンドを実行し、結果をコミットします。ここではパッケージリストを更新し、cowsayパッケージをインストールします。-yフラグはプロンプトに自動的に「yes」と答えます。CMD ["cowsay", "Hello, Docker!"]: この命令は実行コンテナのデフォルトコマンドを提供します。このイメージからコマンドを指定せずにコンテナを起動すると、cowsay "Hello, Docker!"が実行されます。
ファイルを保存するには、Ctrl + X、次に Y、そして Enter を押します。
Dockerfile が準備できたので、イメージをビルドできます。docker build コマンドを使用します。コマンド末尾の . は、Docker に現在のディレクトリ (~/project) で Dockerfile を探すように指示します。また、イメージに my-cowsay-image のような名前でタグを付けます。
docker build -t my-cowsay-image .
このコマンドは Dockerfile の命令をステップバイステップで実行します。ベースイメージのダウンロード(まだ存在しない場合)や cowsay のインストールなど、各ステップが処理されていることを示す出力が表示されます。
ビルドプロセスが完了したら、docker images コマンドを使用してイメージが正常に作成されたことを確認できます:
docker images
出力に my-cowsay-image が表示されるはずです。
最後に、ビルドしたイメージからコンテナを実行して、期待通りに動作するか確認しましょう。
docker run my-cowsay-image
このコマンドは my-cowsay-image を基に新しいコンテナを作成して起動します。Dockerfile で CMD 命令を定義したため、コンテナは自動的に cowsay "Hello, Docker!" を実行し、ターミナル出力に牛が "Hello, Docker!" と言っているのが表示されるはずです。
ビルド引数とラベルを使用したイメージの構築
このステップでは、Dockerfileでビルド引数 (ARG) とラベル (LABEL) を使用する方法を学びます。ビルド引数を使用すると、ビルドプロセスに変数を渡すことができ、Dockerfileをより柔軟に作成できます。ラベルはイメージにメタデータを追加するためのキーと値のペアです。
まず、~/projectディレクトリにいることを確認してください:
cd ~/project
前のステップで作成したDockerfileを修正しましょう。cowsayで表示するメッセージをカスタマイズするためのビルド引数を追加し、イメージにラベルを付けます。
Dockerfileを編集用に開きます:
nano Dockerfile
ARGとLABEL命令を含むように内容を変更します:
FROM ubuntu:latest
ARG MESSAGE="Hello, Docker!"
RUN apt-get update && apt-get install -y cowsay
LABEL maintainer="Your Name <your.email@example.com>"
CMD ["cowsay", "$MESSAGE"]
変更点を見てみましょう:
ARG MESSAGE="Hello, Docker!": この命令は、"Hello, Docker!"というデフォルト値を持つMESSAGEというビルド引数を定義します。この値はビルドプロセス中に上書きできます。LABEL maintainer="Your Name <your.email@example.com>": この命令はイメージにラベルを追加します。ラベルはメンテナーやバージョン、その他の関連メタデータなどの情報を追加するのに便利です。CMD ["cowsay", "$MESSAGE"]:CMD命令を変更して、MESSAGEビルド引数の値を使用するようにしました。
Ctrl + X、次にY、そしてEnterを押して変更したDockerfileを保存します。
では、再度イメージをビルドしますが、今回は--build-argフラグを使用してMESSAGEビルド引数の値を渡します。また、新しいタグmy-custom-cowsay-imageを付けます。
docker build --build-arg MESSAGE="Building with arguments!" -t my-custom-cowsay-image .
ビルドプロセス中の出力を確認してください。ARG命令が処理され、MESSAGEの値が"Building with arguments!"に設定されていることがわかります。
ビルドが完了したら、この新しいイメージからコンテナを実行してみましょう:
docker run my-custom-cowsay-image
今度は、コンテナがカスタムメッセージ"Building with arguments!"を出力するはずです。
追加されたラベルを確認するために、イメージを検査することもできます。イメージ名の後にdocker inspectコマンドを使用します:
docker inspect my-custom-cowsay-image
出力で"Labels"セクションを探してください。Dockerfileで指定した値を持つmaintainerラベルが見つかるはずです。
特定プラットフォーム向けイメージのビルドとファイル出力
このステップでは、特定のプラットフォーム向けに Docker イメージを構築し、ファイルとして出力する方法を学びます。異なるプラットフォーム向けに構築することは、異なるアーキテクチャ(ARM と x86 など)のシステムにアプリケーションをデプロイする際に有用です。ファイルへの出力により、イメージを tar アーカイブとして保存でき、別の Docker 環境に簡単に転送して読み込むことができます。
まず、~/projectディレクトリにいることを確認してください:
cd ~/project
前のステップで使用した同じDockerfileを使用します。catコマンドで内容を確認できます:
cat Dockerfile
出力は次のようになります:
FROM ubuntu:latest
ARG MESSAGE="Hello, Docker!"
RUN apt-get update && apt-get install -y cowsay
LABEL maintainer="Your Name <your.email@example.com>"
CMD ["cowsay", "$MESSAGE"]
次に、linux/arm64プラットフォーム向けにイメージを構築しましょう。--platformフラグを使用します。異なるプラットフォーム向けのビルドには Docker Buildx が必要で、最近の Docker インストールには通常含まれています。
docker build --platform linux/arm64 -t my-arm64-cowsay-image .
このコマンドは ARM64 アーキテクチャ向けにイメージを構築します。以前のビルドと同様の出力が表示されますが、ビルドプロセスは異なるアーキテクチャをターゲットにしています。
ビルドが完了したら、イメージをリスト表示して新しく作成されたイメージを確認できます。ARCHITECTURE列にこのイメージのarm64が表示されることに注意してください。
docker images
次に、このイメージを tar ファイルに出力しましょう。これはレジストリを使用せずにイメージを保存・共有するのに便利です。type=tarオプションを指定した--outputフラグを使用します。
docker build --platform linux/arm64 -t my-arm64-cowsay-image . --output type=tar,dest=my-arm64-cowsay-image.tar
このコマンドはイメージを再度ビルドし(ビルドキャッシュを使用する可能性があります)、~/projectディレクトリにmy-arm64-cowsay-image.tarという名前の tar ファイルとして保存します。
lsコマンドを使用して tar ファイルが作成されたことを確認できます:
ls -lh my-arm64-cowsay-image.tar
ファイルとそのサイズが表示されるはずです。この tar ファイルにはmy-arm64-cowsay-imageのすべてのレイヤーが含まれています。このファイルを別のマシンに転送し、docker load -i my-arm64-cowsay-image.tarを使用して読み込むことができます。
キャッシュ制御とシークレット保護を考慮したイメージビルド
このステップでは、Docker ビルドキャッシュの制御方法と、BuildKit のsecretマウントタイプを使用したビルドプロセス中のシークレット処理方法について学びます。ビルドキャッシュはビルドを大幅に高速化できますが、無効にする必要がある場合もあります。シークレットを安全に処理することは、機密情報がイメージレイヤーに埋め込まれるのを防ぐために重要です。
まず、~/projectディレクトリにいることを確認してください:
cd ~/project
キャッシュ制御対象のステップとシークレット処理のデモンストレーションを行うため、Dockerfileを修正しましょう。タイムスタンプを含むファイル作成ステップと、仮想的にシークレットを使用するステップを追加します。
Dockerfileを編集用に開きます:
nano Dockerfile
タイムスタンプファイルを作成するRUNコマンドとシークレット使用のプレースホルダーを含むように内容を変更します:
FROM ubuntu:latest
ARG MESSAGE="Hello, Docker!"
RUN apt-get update && apt-get install -y cowsay
LABEL maintainer="Your Name <your.email@example.com>"
RUN echo "Build time: $(date)" > /app/build_info.txt
## これはシークレットを使用するコマンドのプレースホルダーです
## RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret > /app/secret_info.txt
CMD ["cowsay", "$MESSAGE"]
RUN echo "Build time: $(date)" > /app/build_info.txtを追加しました。このコマンドは、このレイヤーがビルドされた時刻を含む/app/build_info.txtファイルを作成します。デフォルトでは、Docker はレイヤーをキャッシュします。このRUNコマンドより前の命令を変更せずにイメージを複数回ビルドすると、このレイヤーはキャッシュから提供され、タイムスタンプは更新されません。
Ctrl + X、次にY、そしてEnterを押して変更したDockerfileを保存します。
では、新しいタグmy-cached-imageでイメージをビルドしましょう。
docker build -t my-cached-image .
出力を確認してください。最近イメージをビルドした場合、いくつかのステップで---> Using cacheが表示されるかもしれません。
キャッシュ制御を実証するため、今度は--no-cacheフラグを使用してキャッシュを完全に無効にしてイメージを再度ビルドします。
docker build --no-cache -t my-no-cache-image .
命令が変更されていなくても、Docker がすべてのレイヤーを再構築するのがわかります。これは、すべての依存関係を新しく取得したい場合や、前回のビルドがキャッシュを破損する形で失敗した場合に有用です。
次に、シークレットの処理について説明します。コメントアウトされた行## RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret > /app/secret_info.txtは、BuildKit でシークレットを使用する方法を示しています。これを使用するには、BuildKit を有効にし(最近の Docker バージョンではデフォルトで有効になっていることが多い)、--secretフラグを使用してビルド中にシークレットを提供する必要があります。
例えば、シークレットを含むmysecret.txtというファイルがある場合、次のようにビルドします(このコマンドはmysecret.txtファイルがなく、行がコメントアウトされているためそのままでは動作しませんが、構文を示しています):
## docker build --secret id=mysecret,src=mysecret.txt -t my-secret-image .
RUN --mount=type=secret,id=mysecret命令は、シークレットの内容をビルドステップ中のみ/run/secrets/mysecretで利用可能にします。シークレットは最終的なイメージレイヤーには含まれません。これは、API キーやパスワードなどの機密情報をビルド中に処理する安全な方法です。
シークレットファイルがなく、行がコメントアウトされているため、シークレット関連のビルドコマンドは実行しません。ただし、--no-cacheの概念とsecretマウントタイプを理解することは、ビルドを制御し、機密データを処理する上で重要です。
まとめ
この実験では、Dockerfileを使用して Docker イメージを構築する基本を学びました。Ubuntu ベースのシンプルなDockerfileを作成し、パッケージをインストールし、デフォルトコマンドを定義することから始めました。これにより、FROM、RUN、CMDといったコア命令と、タグを付けてdocker buildでイメージを構築する方法を理解しました。
基本を踏まえて、より高度なイメージ構築技術を探求しました。ビルドプロセスをカスタマイズし、イメージにメタデータを追加するために、ビルド引数とラベルをDockerfileに組み込む方法を学びました。また、特定のプラットフォーム向けにイメージを構築し、結果のイメージをファイルに出力する方法を実践し、ビルド出力を制御する方法を実証しました。最後に、ビルドキャッシュの管理とビルドプロセス中のシークレットの安全な取り扱いについて掘り下げ、効率的で安全なイメージ作成のベストプラクティスを強調しました。



