Если вы пытаетесь разобраться, как настроить proxy в GitHub Actions, начните с простого вопроса: что именно должен затрагивать прокси, а что — нет? От этого зависит, зададите ли вы переменные для одного шага, одной job или всего workflow. Ошибётесь — и runner с радостью отправит трафик совсем не туда, куда вы планировали.
GitHub Actions на первый взгляд выглядит просто: YAML-файл, runner, несколько команд. Сложности начинаются, когда скачивание пакета зависает, приватный registry не принимает соединение или сканеру безопасности нужен исходящий доступ через корпоративный прокси. Тогда прокси становится частью workflow, а не просто сетевой деталью.
1. Сначала определите точную область действия прокси в workflow
Начинать нужно с области действия, потому что GitHub Actions — это не один общий shell. Один workflow может содержать 1 job, 5 шагов и несколько разных сетевых путей, и для каждого может потребоваться своё правило. Шаг сборки, который скачивает зависимости, может идти через прокси, а шаг деплоя на внутренний хост — обходить его.
Думайте по слоям. Если прокси нужен только одной команде, задайте его там. Если он нужен каждому шагу в job, определите его на уровне job. Если от него зависит весь workflow, задайте переменные на уровне workflow, а затем оставьте короткий список исключений в NO_PROXY. Звучит скучно, но экономит часы.
Практический пример: сборка Node может требовать прокси для npm install, а следующий шаг, который отправляет запрос во внутренний webhook, не должен идти через тот же шлюз. В таком случае прокси должен быть в шаге или job сборки, а не в шаге деплоя. Универсального решения тут почти не бывает.
2. Храните настройки прокси в секретах репозитория или организации
Не вставляйте данные для прокси прямо в workflow-файлы. Хост и порт прокси могут быть безобидными, но логин и пароль должны храниться в GitHub Secrets или в переменных уровня окружения, защищённых тем же образом. Оставляйте YAML читаемым и не храните секреты в истории коммитов.
Удобный подход — хранить полный URL прокси или разбить значения на отдельные секреты, например PROXY_HOST, PROXY_PORT, PROXY_USER и PROXY_PASS. В любом случае файл workflow остаётся коротким. Это важно, когда потом пять человек будут править один и тот же файл, а один из них окажется очень спешащим.
Секретов репозитория достаточно для одного проекта. Секреты организации имеют больше смысла, когда один и тот же прокси-политикой пользуются несколько репозиториев, особенно в компании с общей CI-сетью. Для более широкого сравнения инструментов конфиденциальности и схем с прокси смотрите раздел руководства по VPN, прокси и приватности.
3. Добавьте переменные окружения прокси на уровне job или шага
Большинство инструментов в GitHub Actions понимают стандартные переменные прокси. Используйте HTTP_PROXY, HTTPS_PROXY и NO_PROXY, а также варианты в нижнем регистре, если инструмент капризничает. Некоторые скрипты читают только имена в верхнем регистре, а некоторые старые библиотеки предпочитают нижний. Укажите оба варианта, если хотите меньше сюрпризов. Для удобства проверки держите рядом список HTTP_PROXY HTTPS_PROXY NO_PROXY GitHub Actions, чтобы быстро понять, что именно задано в окружении.
На уровне job переменные применяются ко всем шагам внутри этой job. На уровне шага — только к следующей команде. Эту разницу легко упустить при быстром редактировании, и тогда одна зависимость установится успешно, а следующая упадёт на следующей строке.
Обычно чистый блок job выглядит так: прокси задаётся в env, учётные данные хранятся в secrets, а команды наследуют окружение. Если одному шагу нужно обойти прокси, переопределите переменную именно там, вместо того чтобы переписывать всю job. Коротко, прямо и проще для проверки.
Если в выводе runner вообще не упоминается прокси, проверьте, читает ли инструмент переменные окружения. Некоторые CLI это делают, некоторые игнорируют их, а некоторым нужен собственный конфигурационный файл. Глоссарий по VPN и прокси поможет, если хотите сначала разобраться в терминах, а уже потом менять настройки.
4. Передавайте настройки прокси в контейнерные job и сервисы
С контейнерными job всё немного иначе, потому что job выполняется внутри контейнера, а не напрямую на хосте runner. Во многих случаях нужно продублировать переменные прокси внутри окружения контейнера, и иногда то же самое относится к service containers. Если забыть об этом шаге, хост сможет выйти к прокси, а контейнер — нет.
Это особенно важно в workflow, где рядом с основной job работают базы данных, браузеры или тестовые сервисы. Контейнеру с базой данных прокси может не понадобиться вообще, а вот тестовому контейнеру, который скачивает бинарник браузера, он, скорее всего, нужен. Правило должно быть явным, а не подразумеваемым.
Есть и практическая тонкость с образами контейнеров. Если у образа есть собственный менеджер пакетов или bootstrap-скрипт, он может отправлять исходящие запросы ещё до первого шага workflow. В таком случае переменные прокси нужно встраивать в определение контейнера, а не добавлять позже через shell-команду. Ранний трафик — это всё равно трафик.
5. Настройте распространённые пакеты и инструменты внутри Actions
Настройка конкретных инструментов — это место, где прячется большинство проблем с прокси в CI. Node, npm, инструменты Python, операции Git, curl и менеджеры пакетов для разных языков могут вести себя по-разному. Одни чисто читают переменные окружения. Другие предпочитают собственную конфигурацию. Третьим нужно и то и другое.
Для Node-workflow установка пакетов обычно — первое испытание. Если npm не может достучаться до registry, проверьте, был ли прокси задан до шага установки и не нужна ли самому registry отдельная конфигурация. То же самое относится к установке Python-пакетов, которая ломается только после первого запроса. Прокси был, инструмент — нет.
Git может быть не менее придирчивым. Действие checkout может сработать, а вот более поздний git fetch внутри скрипта — нет, особенно если скрипт использует другое окружение. Менеджер пакетов в одном шаге и команда Git в другом — это не один и тот же клиент, так что не стоит считать, что одна настройка покроет всё.
Если ваш workflow зависит от доступа к пакетам через фильтруемую сеть, полезно заранее прочитать специализированное руководство, например статью как выбрать VPN, прежде чем окончательно определиться с общей схемой подключения. Прокси — лишь одна часть; маршрут выхода с runner — другая.
6. Обрабатывайте аутентифицированные прокси и скрытые учётные данные
Прокси с аутентификацией — обычное дело в корпоративном CI, и URL часто содержит имя пользователя и пароль. Храните эти значения в secrets, а затем собирайте URL во время выполнения, вместо того чтобы жёстко прописывать его в workflow-файле. Одной утечки в логах достаточно.
GitHub маскирует secrets в выводе логов, но маскирование — не магия. Если скрипт печатает полный URL прокси в debug-строке или выводит значения окружения во время отладки, вы можете раскрыть больше, чем хотели. Делайте debug-вывод узким и не вываливайте все переменные только ради одного значения.
Лучше сначала проверить безопасной командой, например запросом к пакету или метаданным, и убедиться, что команда проходит, не печатая сам прокси. Если прокси требует аутентификацию, воспользуйтесь руководством по лучшим практикам аутентификации прокси для более безопасной работы, прежде чем что-то встраивать в CI.
Небольшое предупреждение: если вы положите учётные данные в secret репозитория и затем будете использовать этот secret в нескольких job, каждая job, которая может прочитать secret, сможет также отправлять трафик через прокси. Это нормально, но решение должно быть осознанным. Учётные данные прокси — это всё ещё учётные данные.
7. Исключайте внутренние хосты и endpoints GitHub через NO_PROXY
NO_PROXY — это та часть, которую обычно откладывают до первой поломки. Потом добавляют один хост, проверяют снова и находят ещё один, который надо было исключить с самого начала. Укажите localhost, loopback-адреса, внутренние домены и любые имена сервисов, которые должны оставаться прямыми. Обычно список получается длиннее, чем ожидается.
Для endpoint GitHub тоже может потребоваться отдельная обработка. Некоторые workflow должны обращаться к сервисам GitHub напрямую, а другие запросы должны идти через прокси. Если отправлять всё через прокси без проверки, можно получить медленные checkout, задержки webhook или неожиданные жалобы на сертификаты. Прокси — не всегда правильный маршрут.
К внутренним именам нужно относиться особенно внимательно, потому что они часто отличаются от публичных всего лишь одним суффиксом. Сборочный сервер может быть доступен как build.local во внутренней сети и совершенно бесполезен через прокси. Добавьте этот хост в NO_PROXY, а не надеясь, что DNS всё сам разрулит.
Если хотите глубже разобраться в правилах обхода, посмотрите как скрыть IP-адрес — там хорошо объяснена логика того, какие запросы должны идти напрямую, а какие нет. Та же привычка разделять внутренний и внешний трафик здесь тоже работает, только уже в контексте CI.
8. Проверьте workflow и устраните сбои прокси
Сначала протестируйте один маленький шаг, прежде чем доверять всему workflow. Простой download, проверка версии или запрос заголовков расскажут больше, чем длинный build-лог. Если этот шаг падает, не меняйте сразу три настройки. Измените одну, запустите снова и посмотрите на результат.
Таймауты обычно указывают на проблему маршрутизации, заблокированный адрес назначения или адрес прокси, до которого runner не может достучаться. Ошибки сертификатов часто означают, что прокси перехватывает TLS, а runner не доверяет цепочке выдачи. Ошибки пакетов могут означать, что прокси в порядке, но инструмент игнорирует переменные окружения. У каждого сбоя свой характер.
Также полезно отделять сбой прокси от ограничений runner. У GitHub-hosted runners есть сетевые правила, которые вы не можете изменить, а у self-hosted runners могут быть правила firewall, которые со стороны выглядят как проблема прокси. Если один runner работает, а другой падает на том же workflow, причина может быть вовсе не в прокси.
Для быстрой проверки здравого смысла убедитесь в исходящем адресе после выполнения workflow. Если нужен чек-лист, статья как проверить, скрыт ли IP всё ещё служит хорошей моделью, хотя контекст там другой. Числа, endpoints и коды ответов рассказывают историю лучше, чем догадки.
Когда сравниваете типы сбоев, держите одно правило: если ошибка появляется до первого сетевого вызова, смотрите на YAML и secrets; если она возникает во время загрузки пакета, смотрите на переменные прокси и конфигурацию инструмента; если проблема есть только на одном хосте, смотрите на NO_PROXY и DNS. Такое разделение на три сценария экономит время. И да, очень много времени.