You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dockerfile中向ssh-agent添加私钥失败问题求助

解决Docker构建Angular项目时SSH密钥无法添加的问题

我来帮你排查下这个问题,看起来你遇到了几个Docker构建中使用SSH密钥的常见坑,咱们一步步解决:

首先,先看你构建命令里的明显错误

你在传递ssh_pub_key的时候用了$(cat ~/.ssh/id_rsa),这会把私钥内容写到公钥文件里,完全不对!应该改成公钥文件的路径:

docker build -t ng-2-docker/client --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" .

然后是Dockerfile里的核心问题

1. ARG的作用域问题

你在FROM之前声明的ARG,在FROM之后的构建阶段是无法直接访问的——因为FROM会启动一个全新的构建上下文,之前的ARG会被重置。所以必须在FROM之后重新声明这些ARG:

FROM node:8.9.4
# 重新声明ARG,让后续指令能访问到构建参数
ARG ssh_prv_key
ARG ssh_pub_key

2. SSH Agent的生命周期问题

每个RUN指令都是一个独立的shell会话,你在一个RUN里启动ssh-agent,到下一个RUN的时候这个进程已经退出了,所以ssh-add的效果根本无法延续到npm i的步骤。必须把启动ssh-agent、添加密钥、安装依赖放在同一个RUN里,确保它们在同一个会话中执行。

3. SSH目录的默认路径问题

你自定义了/ssh目录来存放密钥,但SSH默认会读取~/.ssh下的文件,虽然可以通过配置指定,但用默认路径能减少不必要的问题。

修复后的Dockerfile(基础版)

# Use an official Node runtime as a parent image
FROM node:8.9.4

# 重新声明ARG,确保后续指令能访问构建参数
ARG ssh_prv_key
ARG ssh_pub_key

# Specify working directory in docker container
WORKDIR /app

# 配置SSH目录和权限
RUN mkdir -p /root/.ssh/ && chmod 0700 /root/.ssh/

# 添加密钥并设置正确权限
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub

# 将bitbucket添加到已知主机,避免首次连接的确认提示
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts && chmod 644 /root/.ssh/known_hosts

# 把SSH操作和依赖安装放在同一个RUN,确保会话持续
RUN eval `ssh-agent -s` && \
    ssh-add /root/.ssh/id_rsa && \
    # 安装项目依赖
    npm i && \
    # 安装完成后立即删除密钥,减少泄露风险
    rm -rf /root/.ssh/

# 复制项目文件
COPY . /app

# 启动命令
CMD ["npm", "docker:rogers:local"]

# 暴露端口
EXPOSE 4200

更安全的方案:多阶段构建

上面的基础版虽然能解决问题,但如果有人拿到你的镜像,还是有可能通过镜像层历史提取到SSH密钥(因为rm只是在当前层标记删除,之前的层依然保留密钥)。用多阶段构建可以彻底避免这个问题:

# 第一阶段:仅用于安装依赖,包含SSH密钥操作
FROM node:8.9.4 AS builder

ARG ssh_prv_key
ARG ssh_pub_key

WORKDIR /app

# 配置SSH
RUN mkdir -p /root/.ssh/ && chmod 0700 /root/.ssh/
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts && chmod 644 /root/.ssh/known_hosts

# 复制package文件并安装依赖
COPY package.json package-lock.json* ./
RUN eval `ssh-agent -s` && ssh-add /root/.ssh/id_rsa && npm i

# 第二阶段:构建最终镜像,仅复制需要的文件
FROM node:8.9.4

WORKDIR /app

# 从builder阶段复制已经安装好的node_modules
COPY --from=builder /app/node_modules ./node_modules
# 复制项目源码
COPY . .

# 启动命令
CMD ["npm", "docker:rogers:local"]

# 暴露端口
EXPOSE 4200

这个方案里,SSH密钥只存在于builder阶段的镜像中,最终的镜像完全不包含任何SSH相关的文件,安全性大大提升。

额外注意事项

如果你的SSH私钥是带密码的,ssh-add会要求输入密码,这时候构建会卡住。建议你生成一个无密码的SSH密钥专门用于Docker构建,并且只给这个密钥授予拉取目标私有仓库的权限,最小化风险。

内容的提问来源于stack exchange,提问作者Usman Tahir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:24:55