繁体   English   中英

如何创建一个依赖于托管在 gitlab 子组中的私有 go 包的 docker 镜像?

[英]How to create a docker image which depends on private go packages that are hosted within a subgroup in gitlab?

我正在开发一个导入私有包的 go 项目。 私有包 repo 位于 gitlab 的一个子组中。 我使用~/.netrc文件设置了我的开发环境并设置了GOPRIVATE="gitlab.mycompany.io"并且一切正常。

但是,在 docker build 期间运行go mod download总是失败。

真正奇怪的是,如果我构建一个包含RUN go mod download之前所有步骤的容器,我可以交互地运行容器并在容器内执行go mod download而不会出现问题。

这是我的Dockerfile样子:

FROM golang:latest AS builder

# Adds .netrc
ARG NETRC
RUN echo $NETRC > ~/.netrc
ENV GOPRIVATE="gitlab.mycompany.io/*"
ARG SSH_PRIVATE_KEY
RUN mkdir ~/.ssh && echo "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
RUN echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa && chmod 0600 ~/.ssh/id_rsa

WORKDIR /app
COPY . .

RUN go mod download && go mod verify
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s"


# FROM scratch (...etc.)

我使用以下命令运行它,其中NETRCSSH_PRIVATE_KEY包含这些文件的 cat 输出。

docker build --no-cache --build-arg NETRC=$NETRC --build-arg SSH_PRIVATE_KEY=$SSH_PRIVATE_KEY -t test-downloader .

这个Dockerfile失败了:

remote: 
        remote: ========================================================================
        remote: 
        remote: The project you were looking for could not be found.
        remote: 
        remote: ========================================================================
        remote: 
        fatal: Could not read from remote repository.

        Please make sure you have the correct access rights
        and the repository exists.

谁能帮我理解:

  1. 当 docker 将命令作为构建步骤运行时和我以交互方式运行容器时,环境之间是否存在差异?
  2. 如何使这项工作? :)

附加信息:

  1. .netrc、.gitconfig 和 ssh 密钥在容器内看起来应该如此。
  2. 我曾尝试使用.git-credentials和 git url 进行身份验证(在 git config 中使用insteadOf )。 这失败并出现相同的错误,并且当我在具有所有前述步骤的容器中运行go mod download时也会失败。
  3. 我已经尝试在go.mod文件中使用各种替换指令来将 mod 指向正确的包,这样的尝试是:
    ...
    gopkg.in/yaml.v2 v2.2.7
)

replace gitlab.mycompany.io/maingroup/subgroup/myapp v0.0.0 => gitlab.mycompany.io/maingroup/subgroup/myapp.git v0.0.0


对我有用的替代解决方案

也许不是您正在寻找的答案,但对我有用的方法是不要尝试在您的 Dockerfile 中进行任何类型的身份验证或凭据内容,而是继续供应应用程序。 我个人不喜欢必须有一个供应商文件夹,但这比必须在 Docker 中处理身份验证要好。

您将在 Docker 命令之外运行go mod tidygo mod vendor ,提交该文件,然后您的 Dockerfile 将是这样的(路径和工作目录可能不是正确的,相关部分是如何构建):

FROM golang:1.13-alpine AS build-stage

WORKDIR /app

COPY . /app
RUN go build -mod=vendor

# Final Stage
FROM alpine

RUN mkdir /app
WORKDIR /app

# Copy only the binary so that your Docker image does not have the uncompiled code.
COPY --from=build-stage  /app/APP_NAME .

EXPOSE 3000

ENTRYPOINT ./APP_NAME

我没有尝试过的更清洁的解决方案

另一个解决方案是弄清楚如何使用 GOPROXY。 我还没有尝试过该解决方案,但它会是一种更清洁的方法。 你可以使用类似雅典的东西: https : //docs.gomods.io/configuration/authentication/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM