Docker BuildKitの
RUN --mount オプションを使うと、パッケージキャッシュをビルド間で共有してビルド時間を大幅に短縮できます。また --mount=type=secret を使えば、APIキーやSSH鍵をイメージにまったく含めずにビルド時だけ参照することもできます。この記事では、Rocky Linux 9 / Docker 26.x(BuildKit有効)の実機で動作確認した
RUN --mount の実践的な使い方を、ビルド時間の実測値とともに解説します。cacheマウントでビルドを速くし、secretマウントでビルドを安全にする2本の柱を中心に説明します。この記事のポイント
・RUN --mount=type=cacheでpip/npm/aptのキャッシュを再利用できる
・RUN --mount=type=secretでAPIキーをイメージに含めずビルドに使える
・DOCKER_BUILDKIT=1(または compose build)で自動的に有効になる
・docker build --secret id=...,src=...でsecretをビルドに渡す
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
BuildKitとRUN --mountを使う前提条件
RUN --mount はDockerのビルドエンジンであるBuildKitの機能です。Docker 23.0以降はBuildKitがデフォルトで有効になっているため、特別な設定は不要です。Docker 20.x系では次のように環境変数で明示的に有効化します。# Docker 23.0以降: デフォルトで有効(設定不要) # Docker 20.x系: 環境変数で有効化 $ export DOCKER_BUILDKIT=1 $ docker build -t myapp:latest . # バージョン確認 $ docker version --format '{{.Server.Version}}' 26.1.4 # BuildKitが有効か確認 $ docker buildx version github.com/docker/buildx v0.14.1 ...
# syntax=docker/dockerfile:1 をDockerfileの1行目に書くと、常に最新のBuildKit構文を使うことを明示できます。実務では必ず付けておく習慣にしておくとよいです。RUN --mount=type=cacheでビルドを高速化する
--mount=type=cache は、ビルドのたびに消えてしまうディレクトリをビルド間で永続化(キャッシュ)します。パッケージマネージャーのキャッシュディレクトリをマウントすることで、2回目以降のビルドでダウンロードをスキップできます。1. Pythonのpip installを高速化する
通常のpip installはビルドのたびにPyPIからダウンロードします。--cache-dir とcache mountを組み合わせることで、2回目以降のビルドでキャッシュを再利用できます。# syntax=docker/dockerfile:1 FROM python:3.12-slim-bookworm WORKDIR /app COPY requirements.txt . # cache mount でpipキャッシュを保持(ビルド間で共有) RUN --mount=type=cache,target=/root/.cache/pip pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "main.py"]
ポイントは
target=/root/.cache/pip の指定です。pipはデフォルトでこのパスにキャッシュを保存するため、ここをcache mountにするとビルド間でキャッシュが再利用されます。2. Node.jsのnpm ciを高速化する
# syntax=docker/dockerfile:1 FROM node:20-alpine WORKDIR /app COPY package*.json ./ # npmのキャッシュを保持(UID=1000のnodeユーザー向けパスを指定) RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline COPY . . RUN npm run build CMD ["node", "dist/index.js"]
3. apt-getのパッケージキャッシュを保持する(Debian/Ubuntu)
# syntax=docker/dockerfile:1 FROM ubuntu:24.04 # cache mountで apt パッケージをキャッシュ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt apt-get update && apt-get install -y --no-install-recommends build-essential libpq-dev
/var/cache/apt(ダウンロード済みパッケージ)と /var/lib/apt(パッケージ一覧)の両方をマウントします。なお、cache mountのデータはビルドキャッシュとして
docker system prune --volumes で削除されます。通常の docker system prune では削除されないため、ディスクを圧迫している場合は注意が必要です。
Dockerハンズオン研修の詳細を見る >>
RUN --mount=type=secretでビルドを安全にする
--mount=type=secret は、ビルド時にのみ参照できる機密情報(APIキー・認証トークン・SSHパスワード)をコンテナへ渡します。このマウントはビルド後のイメージレイヤーに残りません。従来は
ARG MY_API_KEY でビルド引数を渡すケースが多かったですが、docker history でAPIキーが丸見えになる重大なリスクがありました。secret mountはこのリスクを根本から解消します。1. 秘密ファイルをsecret mountで渡す
# syntax=docker/dockerfile:1 FROM python:3.12-slim-bookworm WORKDIR /app COPY requirements.txt . # secret mountでGitHub Packagesの認証トークンを渡す # /run/secrets/github_token にマウントされる(ビルド後は消える) RUN --mount=type=secret,id=github_token pip install --extra-index-url "https://$(cat /run/secrets/github_token)@pypi.example.com/simple/" -r requirements.txt COPY . . CMD ["python", "main.py"]
/run/secrets/<id> がマウントポイントです。id に指定した名前と対応するファイルが、ビルド中だけそこに置かれます。2. ビルド時のコマンドでsecretを渡す
# APIキーを一時ファイルに書き出す $ echo "ghp_xxxxxxxxxxxxxxxxxxxx" > /tmp/github_token.txt # ビルド時に --secret フラグで渡す $ docker build --secret id=github_token,src=/tmp/github_token.txt -t myapp:latest . # 後処理: 一時ファイルを削除 $ rm /tmp/github_token.txt # 念のためイメージにsecretが残っていないことを確認 $ docker history myapp:latest IMAGE CREATED CREATED BY SIZE a1b2c3d4e5f6 2 seconds ago RUN /bin/sh -c pip install ... 45.2MB # ← APIキーの文字列はどこにも見えない
3. CI/CDパイプラインでのsecret mount
GitHub Actionsから渡す場合は次のパターンが一般的です。# .github/workflows/build.yml(抜粋) - name: Build Docker image run: | echo "${{ secrets.PYPI_TOKEN }}" > /tmp/pypi_token docker build --secret id=pypi_token,src=/tmp/pypi_token -t myapp:latest . rm /tmp/pypi_token
トラブルシュート|よくあるエラーと対処法
「failed to solve: failed to load LLB」エラーが出る
Dockerfileの1行目に# syntax=docker/dockerfile:1 が書かれていない場合や、古いDockerバージョンで発生します。# Dockerfileの先頭行を確認 $ head -1 Dockerfile # syntax=docker/dockerfile:1 ← これが必要 # DockerのBuildKitが有効か確認 $ docker info | grep "buildkit" buildkitd: true
cache mountがビルド間で効いていない
--mount=type=cache の target パスがパッケージマネージャーの実際のキャッシュパスと一致していない場合に発生します。# pipのキャッシュパスをコンテナ内で確認 $ docker run --rm python:3.12-slim pip cache dir /root/.cache/pip # npmのキャッシュパスを確認 $ docker run --rm node:20-alpine npm config get cache /root/.npm
secret mountで「no such file or directory」エラー
--secret id=XXX,src=...ファイルパス... で指定したファイルが存在しないか、パスが間違っています。# NG: srcファイルが存在しない $ docker build --secret id=mytoken,src=/tmp/mytoken.txt . ERROR: secret file '/tmp/mytoken.txt': no such file or directory # OK: ビルド前にsrcファイルの存在を確認 $ test -f /tmp/mytoken.txt && echo "OK" || echo "ファイルが存在しません" OK $ docker build --secret id=mytoken,src=/tmp/mytoken.txt .
本記事のまとめ
RUN --mount を使うことでDockerfileのビルド効率とセキュリティを同時に改善できます。cache mountでビルド時間を短縮し、secret mountで機密情報の漏洩リスクを根本から排除する——この2つはどちらも本番環境に持ち込むべき重要な設計パターンです。| やりたいこと | RUN --mount 設定 |
|---|---|
| pip installのキャッシュを再利用する | RUN --mount=type=cache,target=/root/.cache/pip pip install ... |
| npm ciのキャッシュを再利用する | RUN --mount=type=cache,target=/root/.npm npm ci ... |
| apt-getのキャッシュを保持する | RUN --mount=type=cache,target=/var/cache/apt apt-get ... |
| APIキーをイメージに含めずビルドに使う | RUN --mount=type=secret,id=mytoken cat /run/secrets/mytoken |
| ビルド時にsecretを渡すコマンド | docker build --secret id=mytoken,src=/tmp/token.txt . |
cache mountとsecret mountを習得したら、次のステップとして
--mount=type=ssh(プライベートリポジトリへのSSHアクセス)や --mount=type=bind(ホストのファイルをビルド時に参照)も組み合わせると、より高度なDockerfile設計が実現できます。
Dockerハンズオン研修の詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Dockerボリュームのバックアップと復元|named volumeのデータを別サーバーへ移行する実践手順
- この記事の属するカテゴリ:Dockerへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます