首页/云/Docker 容器速查/RUN --mount=type=ssh 转发 SSH 代理
镜像与构建107 条

RUN --mount=type=ssh 转发 SSH 代理

构建阶段通过 SSH 代理访问私有 Git 仓库,密钥不落盘进镜像;构建命令加 --ssh default 启用。

Docker 容器速查云更新于 2026-10-13

指令解决什么问题

BuildKit 的 RUN --mount=type=ssh 让构建步骤借用宿主 ssh-agent 的转发通道:私钥始终留在宿主内存中,不进构建上下文、不落进镜像层。它主要解决构建期从私有 Git 仓库拉代码的需求。使用前提是构建走 BuildKit(Buildx 或新版 docker build)、Dockerfile 声明 syntax、构建命令带 --ssh 参数,并且宿主的 agent 已加载对应私钥。

基本信息

用途构建期通过 SSH 代理访问私有仓库
Dockerfile 写法RUN --mount=type=ssh <命令>
构建侧参数docker build --ssh default .
前提宿主 ssh-agent 已加载私钥(ssh-add -l 可见)
依赖BuildKit,需在 Dockerfile 首行声明 syntax

典型使用场景

  • 构建期 clone 私有 Git 仓库,拉取内部依赖模块
  • 执行 git submodule update 获取子模块源码
  • 从内部制品服务器拉取构建所需的产物或配置
  • 替代把私钥 COPY 进镜像的危险做法,消除镜像内泄露面
  • CI 流水线用部署密钥按项目授权,密钥只存在于 runner 的 agent 中

Dockerfile 示例

Dockerfile 示例
# syntax=docker/dockerfile:1.7
FROM alpine:3.20 AS build
RUN apk add --no-cache git openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone --depth 1 git@github.com:team/repo.git /src/repo && rm -rf /src/repo/.git
# 说明:--mount=type=ssh 只对这一条 RUN 生效,其他步骤看不到私钥

构建侧启用

构建侧启用
eval "$(ssh-agent -s)"        # 启动 agent
ssh-add ~/.ssh/id_ed25519      # 加载私钥
ssh-add -l                     # 确认私钥已加载
docker build --ssh default -t app/api:1.4.2 .    # 构建时转发 agent
docker build --ssh key=~/.ssh/deploy_key -t app/api:1.4.2 .   # 指定密钥文件

要素对照

要素位置说明
--mount=type=sshRUN 行仅该步有效,不会残留到后续层
--ssh default构建命令引用 SSH_AUTH_SOCK 指向的 agent
--ssh key=路径构建命令直接用指定私钥文件,不依赖 agent
known_hostsDockerfile 内私有仓库首次连接需要已知主机指纹
容器内没有 SSH_AUTH_SOCK 时构建会报错,先在本机确认 ssh-add -l 能列出密钥;CI 环境需要在流水线里显式启动 agent 并加载部署密钥。
构建完成把 .git 目录删掉,避免仓库地址、提交历史和远端配置随镜像分发出去。

使用前的前提检查

  • 构建是否走 BuildKit:docker buildx version 能输出,且构建日志出现分步进度
  • 宿主 agent 是否真的加载了私钥:ssh-add -l 能列出对应指纹
  • 私有仓库指纹是否已写进 known_hosts,避免构建中途等待交互式确认
  • CI 环境是否把部署密钥安全注入 runner 的 agent,而不是提交进仓库

易错点

  • 拉完代码不清 .git:仓库地址与提交历史被带进镜像,属于信息泄露面
  • ssh-keyscan 直接信任返回的指纹存在中间人风险,生产建议预先核对指纹后固化 known_hosts
  • 把私钥 COPY 进镜像再删除:删除只发生在新的层,旧层中的私钥仍可用 docker save 提取,必须改用 SSH 转发或构建期 secret
  • 本地能构建、CI 失败:runner 上没有 agent 或未加载密钥,排查时先看 ssh-add -l 的输出

数据来源与参考

  • Docker 官方文档:Build with SSH(docs.docker.com/build/building/secrets)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌