这里有两个问题需要解决:
1.如何让 Docker 安全地访问本地 SSH 密钥?
2.如何告诉 Go 不要使用公共注册表来获取私有包?
简答
-
从 Docker v18.09 开始,有一个内置的解决方案可以在构建阶段处理 SSH 身份验证 (more)。与传递构建参数相比,它也更容易、更安全,并且无需多阶段 Docker 构建。
-
Go 有一个 GOPRIVATE 环境变量来识别私有包。 (more)
长答案
一步一步:
1.确保 ssh-agent 已设置并且知道 SSH 密钥
Github 有一个关于这个主题的快速指南,解释了不同操作系统的过程。见Generating a new SSH key and adding it to SSH agent。
2。为 Docker 启用 BuildKit
如果没有 BuildKit,docker build 将无法识别 --ssh 选项。
来自Docker reference:
全新安装 docker 最简单的方法是设置
DOCKER_BUILDKIT=1 调用 docker build 时的环境变量
命令,如:
$ DOCKER_BUILDKIT=1 docker build .
通过以下方式启用 docker BuildKit
默认,在/etc/docker/daemon.json 功能中设置守护进程配置
为 true 并重新启动守护进程:
{ "features": { "buildkit": true } }
Docker Desktop 用户可以通过Preferences > Docker Engine管理守护进程配置。
4.更新 Dockerfile
4.1.确保 Git 使用 SSH 而不是 HTTPs
Go 倾向于通过HTTPs 获取公共包。您可以通过更新git 配置来调整此行为:
RUN git config --global url.git@github.com:.insteadOf https://github.com/
您可能也应该在本地计算机上执行此操作。
4.2.在需要的地方请求 SSH 访问
每个需要 SSH 访问的RUN 命令都应该使用type=ssh 挂载。对于
例子:
RUN --mount=type=ssh git clone ...
4.3.确保 Go 知道你的私有包
更新GOPRIVATE变量:
RUN go env -w GOPRIVATE="github.com/your-org/private-repo"
将所有这些放在一起,在以下 Dockerfile 示例中:
FROM golang:1.16.3-alpine3.13
RUN apk update
RUN apk add git openssh
RUN mkdir /app
ADD . /app
WORKDIR /app
# You can replace github.com with any other Git host
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
# Make sure git uses SSH to fetch packages, not HTTPs
RUN git config --global url.git@github.com:.insteadOf https://github.com/
# Make Go knows which packages are private.
RUN go env -w GOPRIVATE="github.com/your-org/private-repo"
# GOPRIVATE is a comma separated list glob-patterns.
# You can use a wildcard to match every repo in an organization:
# e.g.: GOPRIVATE="github.com/your-org/*"
# Mount the build command with type `ssh`.
RUN --mount=type=ssh go get && go build -o main .
CMD ["/app/main"]
6.使用--ssh 选项构建镜像:
默认启用 BuildKit:
$ docker build --ssh default -t my-app:latest .