在golang:alpine Docker镜像中使用ssh-keyscan遇权限问题,求解决方案
使用golang官方镜像构建Docker镜像时,通过SSH拉取私有Go模块可以正常工作,但切换到golang:alpine镜像后,执行go mod download时出现以下权限错误:
[9/9] RUN --mount=type=ssh go mod download:
#13 32.30 go: {ommited}@v0.9.3: reading {ommited}/go.mod at revision v0.9.3: git ls-remote -q origin in /go/pkg/mod/cache/vcs/4dc358100530ae5178fe8ee87660554544c37849403335a46d005c2394bf07a5: exit status 128:
#13 32.30 git@github.com: Permission denied (publickey).
#13 32.30 fatal: Could not read from remote repository.
#13 32.30
#13 32.30 Please make sure you have the correct access rights
#13 32.30 and the repository exists.executor failed running [/bin/sh -c go mod download]: exit code: 1
原因分析
golang镜像基于Debian/Ubuntu发行版,其OpenSSH客户端默认配置会自动识别Docker挂载的SSH代理;而golang:alpine使用的Alpine Linux中,OpenSSH客户端需要显式指定SSH代理路径才能使用宿主机的SSH密钥。
Docker的--mount=type=ssh会将宿主机的SSH代理套接字挂载到容器内的/run/host-services/ssh-auth.sock,但Alpine的Git/SSH不会自动使用这个路径,导致无法获取宿主机的SSH密钥权限。
修复后的Dockerfile
在原有golang:alpine的Dockerfile中,添加Git的SSH命令配置,显式指定代理路径:
FROM golang:alpine RUN apk add --no-cache openssh-client git RUN mkdir -p -m 0700 ~/.ssh RUN ssh-keyscan github.com > /root/.ssh/known_hosts RUN git config --add --global url."ssh://git@github.com/".insteadOf https://github.com/ # 显式指定SSH代理路径,确保容器能访问宿主机SSH代理 RUN git config --global core.sshCommand "ssh -o StrictHostKeyChecking=accept-new -o IdentityAgent=/run/host-services/ssh-auth.sock" WORKDIR /app ENV GOPRIVATE=github.com/{ommited}/* COPY go.mod . COPY go.sum . RUN --mount=type=ssh go mod download
关键说明
core.sshCommand配置告诉Git在执行SSH操作时,使用Docker挂载的代理套接字路径,确保容器能借宿主机的SSH密钥完成私有仓库认证。StrictHostKeyChecking=accept-new用于避免首次连接时的交互式确认(已通过ssh-keyscan添加GitHub主机密钥,也可根据需求去掉该选项)。
内容的提问来源于stack exchange,提问作者ceferrari

