Summary

Docker Build 時需要使用 SSH 私鑰的場景(如克隆私有倉庫)有安全風險。本文介紹兩種解決方案:18.09 以前使用多階段構建傳遞私鑰,18.09 及以後使用 BuildKit 的 --mount=type=ssh 特性,後者更安全且不留痕跡。

When Docker Build needs SSH private keys (e.g., cloning private repos), directly embedding them risks key leakage in image layers. Two solutions: multi-stage build (pre-18.09) and BuildKit --mount=type=ssh (recommended, 18.09+).

Key Points

  • Problem: SSH keys baked into image layers are visible in docker history and image exports.
  • Method 1 (multi-stage): Pass key as ARG SSH_KEY, use in intermediate stage, final stage has no key. Secure if the key doesn’t appear in the final stage.
  • Method 2 (BuildKit --mount=type=ssh): Requires DOCKER_BUILDKIT=1 and # syntax=docker/dockerfile:1. Use RUN --mount=type=ssh <command> — key is mounted at build time, never written to any layer.
  • Build command: docker build --ssh default=/root/.ssh/id_rsa .
  • Multi-key support: --mount=type=ssh,id=github_ssh_key with multiple --ssh flags.
  • Common error: Host key verification failed — fix with ssh-keyscan github.com >> known_hosts or disable StrictHostKeyChecking.

Insights

--mount=type=ssh is the clearly superior approach: the key never touches any image layer, it’s explicit about which RUN commands have key access, and it works with docker buildx for multi-arch builds. The multi-stage approach still has the key in intermediate layers which could be cached locally. In CI/CD contexts, use --ssh default=$SSH_AUTH_SOCK to forward the SSH agent socket rather than a raw key file.

Connections

Raw Excerpt

使用 --mount=type=ssh,既能正常使用上 SSH Private Key,又能使其在鏡像中不留痕跡。完美!