1. 導入:なぜENVやARGで機密情報を扱ってはいけないのか
DockerでプライベートなGitHubリポジトリからライブラリをインストールしたり、パッケージサーバーにログインしたりする際、皆さんはどうしていますか?よくあるのは「ENV命令でトークンを渡す」という方法ですが、これは非常に危険です。Dockerのイメージはレイヤー構造で保存されるため、ENVで渡した機密情報は中間レイヤーにそのまま残り、`docker history`コマンドなどで誰でも中身を見ることができてしまいます。これを解決するのが、今回紹介する「Docker BuildKit Secrets」です。
2. 基礎知識:BuildKitと–mount=type=secret
BuildKitは、Dockerの次世代ビルドエンジンです。これを使うことで、ビルド中にのみ一時的に機密情報をマウントし、ビルドが終われば自動的に破棄される仕組みが使えます。
–mount=type=secret:このオプションを使うと、ホストマシンのファイルを一時的にコンテナ内の指定パスへマウントします。重要なのは、このファイルが「イメージレイヤーには一切書き込まれない」ということです。メモリ上でのみ処理が完結するため、秘匿情報を安全に扱えます。
3. 実装/解決策:セキュアなビルドの手順
以下の手順で進めます。
1. Dockerfile内で `–mount=type=secret` を使用してファイルを読み込む。
2. ビルド実行時に `–secret` オプションでホスト側の鍵ファイルを指定する。
4. サンプルプログラム:プライベートトークンの読み込み例
以下は、プライベートなnpmパッケージをインストールする際にトークンを使う例です。
Dockerfile
syntax=docker/dockerfile:1
FROM node:18-slim
ビルド時にのみアクセス可能な場所にシークレットをマウントして実行
id=npmrc は識別子、targetはコンテナ内のパス
RUN –mount=type=secret,id=npmrc,target=/root/.npmrc \
npm install
実行コマンド
docker buildx build –secret id=npmrc,src=$HOME/.npmrc -t my-app:latest .
※コード解説:
・Dockerfileの1行目:BuildKitの機能を有効にします。
・RUN命令:`–mount`を使って、ホスト側の `.npmrc` を一時的にコンテナ内の `/root/.npmrc` に配置します。
・実行コマンド:`–secret`で、ホスト側にある本物のファイルを指定します。ビルド完了後、コンテナ内のファイルは消滅し、イメージにも残りません。
5. 応用・注意点:現場での活用ポイント
・SSHキーの場合:`id=ssh` を使用し、`target=/root/.ssh/id_rsa` のようにマウントすれば、プライベートリポジトリからの `git clone` も安全に行えます。
・陥りやすい罠:BuildKitが有効になっていない環境ではエラーになります。Docker Desktopを使用している場合は標準で有効ですが、古い環境では `DOCKER_BUILDKIT=1` という環境変数を指定して実行してください。
・注意点:この手法は「ビルド時」のみ有効です。コンテナの「実行時(Runtime)」に機密情報が必要な場合は、KubernetesのSecretやDockerのSecret機能など、別の仕組みを検討してください。
安全なビルド環境を作ることは、エンジニアとしての第一歩です。ぜひ今日からENVでの秘密鍵管理を卒業しましょう!

コメント