Как создать образ docker, который зависит от частных go пакетов, которые размещены в подгруппе в gitlab? - PullRequest
2 голосов
/ 11 марта 2020

Я работаю над проектом go, который импортирует приватный пакет. Закрытое хранилище пакетов находится внутри подгруппы в gitlab. Моя среда разработки настроена с использованием файла ~/.netrc и настройки GOPRIVATE="gitlab.mycompany.io", и все работает нормально.

Однако, выполнение go mod download во время сборки docker всегда дает сбой.

REALY WIERD состоит в том, что если я создаю контейнер, включающий все шаги до 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.)

Я выполняю это с помощью следующей команды, где NETRC и SSH_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. .netr c, .gitconfig и s sh выглядят так, как они должны быть внутри контейнер.
  2. Я попытался пройти аутентификацию с .git-credentials и git url (используя insteadOf в git config). Это происходит с той же ошибкой, а также с ошибкой, когда я запускаю go mod download внутри контейнера, в котором есть все предыдущие шаги.
  3. Я попытался использовать всевозможные директивы замены в файле go.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


1 Ответ

1 голос
/ 16 марта 2020

Альтернативное решение, которое сработало для меня

Возможно, не тот ответ, который вы ищете, но способ, который сработал для меня, состоял бы в том, чтобы не пытаться выполнять какие-либо действия по аутентификации или учетным данным в вашем Dockerfile и go с продажей приложений. Мне лично не нравится иметь папку поставщика, но это лучше, чем иметь дело с аутентификацией в Docker.

. Вы бы запустили go mod tidy и go mod vendor вне команды Docker, зафиксировали это и тогда ваш 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/

...