Avatar ·

Как правильно настроить `go get` для работы с приватным Git-репозиторием?

Привет! Я пишу на Go уже пару месяцев и столкнулся с проблемой, которую не могу решить уже третий день. В нашем проекте есть несколько внутренних библиотек, которые лежат в приватных репозиториях на корпоративном GitLab. Когда я пытаюсь выполнить `go get ourcompany.com/scm/team/lib/internal-utils`, получаю ошибку: ``` go: ourcompany.com/scm/team/lib/internal-utils@v1.0.0: unrecognized import path "ourcompany.com/scm/team/lib/internal-utils": https fetch: Get "https://ourcompany.com/scm/team/lib/internal-utils?go-get=1": dial tcp: lookup ourcompany.com: no such host ``` Я пробовал прописать в `.gitconfig`: ``` [url "git@ourcompany.com:"] insteadOf = https://ourcompany.com/ ``` Но это не помогло. Также я слышал про `GOPRIVATE`, `GOFLAGS` и `go env -w`, но не понимаю, как их правильно использовать. В модулях (`go.mod`) я указал `require` на нужную версию, но `go mod tidy` всё равно падает с ошибкой аутентификации. Подскажите, как правильно настроить окружение, чтобы `go get` работал с приватными репозиториями? Используем Go 1.21. Спасибо! <<>>

Корень проблемы: Go не знает, как аутентифицироваться

Когда вы выполняете go get, Go пытается скачать модуль через HTTPS. Для публичных репозиториев это работает, но для приватных требуется аутентификация. Ошибка no such host часто возникает, если ваш DNS не разрешает внутренний адрес, или если вы используете относительный URL. Но главная причина — Go по умолчанию не передаёт SSH-ключи или токены при HTTPS-запросах.

Решение: настройка GOPRIVATE и Git-конфига

Вот пошаговая инструкция для Go 1.13+ (включая 1.21).

Шаг 1. Укажите приватные модули

Установите переменную окружения GOPRIVATE. Она говорит Go, что для этих путей не нужно обращаться к публичным зеркалам (например, proxy.golang.org) и проверять контрольные суммы (sum.golang.org).

go env -w GOPRIVATE=ourcompany.com/*

Если у вас несколько доменов, укажите их через запятую: GOPRIVATE=ourcompany.com,git.internal.org

Шаг 2. Настройте Git на использование SSH вместо HTTPS

Go использует Git для клонирования репозиториев. Если вы настроите Git так, чтобы он заменял HTTPS на SSH, то аутентификация будет проходить по SSH-ключам. Добавьте в ~/.gitconfig:

[url "git@ourcompany.com:"]
    insteadOf = https://ourcompany.com/

Важно: проверьте, что ваш SSH-ключ добавлен в GitLab/GitHub и что URL репозитория начинается с git@ourcompany.com: (без //). Если ваш GitLab использует другой порт (например, 2222), укажите его явно: ssh://git@ourcompany.com:2222/.

Шаг 3. Проверьте доступность через SSH

Выполните в терминале:

ssh -T git@ourcompany.com

Если всё ок — увидите приветствие GitLab. Если нет — проверьте ключи в ~/.ssh/id_rsa.pub и добавьте их в настройки аккаунта.

Шаг 4. Для HTTPS с токеном (альтернатива SSH)

Если SSH не подходит, используйте личный токен доступа (GitLab: Settings → Access Tokens). Настройте Git на хранение токена:

git config --global credential.helper store
echo "https://USERNAME:TOKEN@ourcompany.com" > ~/.git-credentials

Тогда go get будет использовать HTTPS с токеном.

Итоговый чек-лист

  • Выполните go env -w GOPRIVATE=ourcompany.com/*
  • Настройте ~/.gitconfig на SSH
  • Проверьте SSH-ключи
  • Очистите кэш: go clean -modcache
  • Попробуйте снова: go get ourcompany.com/scm/team/lib/internal-utils@latest

Если ошибка осталась — проверьте, что go.mod вашего модуля содержит правильную строку require, и что тег в Git совпадает с версией.

<<>>

Дополнительный подход: использование GOFLAGS и GONOSUMCHECK

Если вы не хотите или не можете менять глобальные настройки Git (например, в CI/CD), можно обойтись только переменными окружения Go. Этот метод полезен, когда репозиторий доступен по HTTPS с токеном, но вы не хотите хранить его в .gitconfig.

Настройка для CI/CD или временного окружения

export GOPRIVATE=ourcompany.com/*
export GONOSUMCHECK=ourcompany.com/*
export GOFLAGS="-insecure"  # только если сервер использует самоподписанный сертификат
export GIT_TERMINAL_PROMPT=0  # отключает запрос пароля

Затем используйте git config --global url."https://USERNAME:TOKEN@ourcompany.com".insteadOf "https://ourcompany.com" прямо в скрипте сборки. Это временно изменит конфиг для текущей сессии.

Важно про GONOSUMCHECK

Go проверяет контрольные суммы модулей через sum.golang.org. Для приватных репозиториев эта проверка не работает, поэтому GONOSUMCHECK отключает её для вашего домена. Без этого go mod tidy может падать с ошибкой 410 Gone.

Этот подход идеален для Docker-образов или GitLab CI, где вы не хотите править глобальные конфиги. Но помните: токен в открытом виде — это риск, используйте переменные окружения CI (например, $CI_JOB_TOKEN в GitLab).