Ваш пайплайн падает с ошибкой 403 Forbidden или Connection refused при попытке обратиться к внешнему API или скачать зависимость? Скорее всего, проблема в том, что IP-адрес вашего CI/CD сервера заблокирован на стороне ресурса. Прокси решает эту проблему: вы маршрутизируете трафик через нужный IP и пайплайн работает без сбоев. В этой статье — пошаговые инструкции для GitHub Actions, GitLab CI и Jenkins.
Зачем прокси в CI/CD: реальные сценарии
CI/CD пайплайны работают на серверах с фиксированными IP-адресами — облачных раннерах GitHub, GitLab или на собственных Jenkins-агентах. Эти IP хорошо известны, и многие внешние сервисы либо блокируют их, либо ограничивают количество запросов. Вот конкретные ситуации, когда без прокси не обойтись:
Доступ к гео-ограниченным ресурсам
Многие корпоративные npm-реестры, Maven-репозитории и внутренние API доступны только из определённых стран или IP-диапазонов. Если ваш GitHub Actions раннер находится в регионе, который заблокирован на уровне firewall целевого сервиса, пайплайн не сможет скачать зависимости или отправить данные. Прокси с нужной геолокацией решает эту задачу без изменения инфраструктуры.
Rate limiting и блокировки по IP
Облачные раннеры GitHub Actions используют IP из диапазонов Microsoft Azure. Многие публичные API знают эти диапазоны и применяют к ним жёсткие лимиты — или блокируют полностью. Например, парсинг публичных данных, запросы к сторонним API во время тестов, скачивание дистрибутивов с ограниченных CDN — всё это регулярно ломается именно из-за IP облачных раннеров. Ротация через прокси позволяет обойти rate limiting.
Интеграционное тестирование с реальными сайтами
Если ваши интеграционные тесты обращаются к реальным веб-сайтам или маркетплейсам (Wildberries, Ozon, Авито, Amazon), эти сайты видят один и тот же IP из раннера при каждом запуске и быстро блокируют его. Прокси с ротацией IP позволяет тестам проходить стабильно без капч и блокировок.
Доступ к внутренним корпоративным ресурсам
Корпоративные сети часто закрыты от внешнего мира. Если пайплайн должен деплоить на внутренний сервер или обращаться к закрытому API, прокси (или SOCKS5-туннель) внутри корпоративной сети становится мостом между облачным раннером и закрытой инфраструктурой.
Тестирование рекламных и маркетинговых интеграций
Команды, работающие с Facebook Ads API, TikTok Ads API или Google Ads API, нередко автоматизируют создание кампаний через CI/CD. Эти платформы имеют строгие правила по IP: запросы с IP дата-центров могут блокироваться или требовать дополнительной верификации. Резидентные прокси в пайплайне делают запросы похожими на обычный пользовательский трафик.
Какой тип прокси выбрать для пайплайна
Выбор типа прокси зависит от задачи. Для CI/CD пайплайнов актуальны три варианта — у каждого свои плюсы и ограничения:
| Тип прокси | Скорость | Доверие сайтов | Лучше всего для |
|---|---|---|---|
| Прокси дата-центров | Очень высокая | Среднее | Скачивание зависимостей, внутренние репозитории, быстрые API без строгих проверок |
| Резидентные прокси | Средняя | Высокое | Интеграционные тесты с реальными сайтами, рекламные API (Facebook, TikTok), маркетплейсы |
| Мобильные прокси | Средняя | Максимальное | Тесты мобильных API, работа с платформами с максимальными антибот-защитами |
Практическое правило:
Если задача — скачать пакеты или обратиться к внутреннему сервису, берите прокси дата-центров — они быстрые и дешевле. Если задача — тесты на реальных сайтах или работа с рекламными платформами — нужны резидентные прокси. Протокол SOCKS5 предпочтительнее HTTP/HTTPS, так как он прозрачнее работает с нестандартными портами и протоколами.
Настройка прокси в GitHub Actions
GitHub Actions — самый популярный CI/CD инструмент на сегодня. Настройка прокси здесь делается через переменные окружения и секреты репозитория. Разберём пошагово.
Шаг 1: Добавьте данные прокси в секреты репозитория
Никогда не вписывайте логин и пароль прокси прямо в YAML-файл workflow. Используйте GitHub Secrets:
- Откройте репозиторий → Settings → Secrets and variables → Actions
- Нажмите New repository secret
- Создайте секрет
PROXY_URLсо значением видаhttp://user:[email protected]:port
Шаг 2: Используйте переменные окружения в workflow
Большинство инструментов (curl, wget, npm, pip, Maven) автоматически подхватывают стандартные переменные окружения HTTP_PROXY, HTTPS_PROXY и NO_PROXY. Пример workflow:
name: Build with Proxy
on: [push]
env:
HTTP_PROXY: ${{ secrets.PROXY_URL }}
HTTPS_PROXY: ${{ secrets.PROXY_URL }}
NO_PROXY: localhost,127.0.0.1,internal.company.com
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Run integration tests
run: npm test
- name: Call external API
run: |
curl -v https://api.example.com/data
Шаг 3: SOCKS5 прокси в GitHub Actions
Если вы используете SOCKS5 (рекомендуется для большинства задач), стандартных переменных окружения недостаточно — нужен локальный туннель. Используйте утилиту proxychains или настройте microsocks:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Setup SOCKS5 proxy tunnel
run: |
sudo apt-get install -y proxychains4
echo "socks5 proxy.host 1080 user password" >> /etc/proxychains4.conf
- name: Run command through SOCKS5
run: proxychains4 curl https://restricted-resource.com/api
Настройка прокси для конкретных инструментов
Некоторые инструменты игнорируют системные переменные и требуют отдельной настройки:
| Инструмент | Как настроить прокси |
|---|---|
| npm / yarn | npm config set proxy http://user:pass@host:port |
| pip (Python) | pip install --proxy http://user:pass@host:port package |
| Maven | Через settings.xml секция <proxies> |
| Gradle | systemProp.https.proxyHost=host в gradle.properties |
| Git | git config --global http.proxy http://user:pass@host:port |
| Docker build | --build-arg HTTP_PROXY=http://user:pass@host:port |
Настройка прокси в GitLab CI
GitLab CI предоставляет несколько уровней для задания переменных окружения: на уровне проекта, группы или инстанса. Это делает управление прокси более гибким по сравнению с GitHub Actions.
Шаг 1: Добавьте переменные в GitLab CI/CD Variables
- Откройте проект → Settings → CI/CD → раздел Variables
- Нажмите Add variable
- Добавьте переменную
PROXY_URLс типом Masked (скрывает значение в логах) - Значение:
http://user:[email protected]:port
Шаг 2: Используйте переменные в .gitlab-ci.yml
variables:
HTTP_PROXY: $PROXY_URL
HTTPS_PROXY: $PROXY_URL
NO_PROXY: "localhost,127.0.0.1,.internal.company.com"
stages:
- build
- test
- deploy
build:
stage: build
image: node:20-alpine
script:
- npm ci
- npm run build
integration_tests:
stage: test
image: python:3.11
script:
- pip install -r requirements.txt
- pytest tests/integration/
deploy:
stage: deploy
script:
- curl -X POST https://api.external-service.com/deploy
-H "Authorization: Bearer $DEPLOY_TOKEN"
-d '{"version": "$CI_COMMIT_SHA"}'
Прокси только для отдельных джобов
Если прокси нужен не везде (например, только для интеграционных тестов, но не для сборки), задавайте переменные на уровне конкретного джоба, а не глобально:
integration_tests:
stage: test
variables:
HTTP_PROXY: $PROXY_URL
HTTPS_PROXY: $PROXY_URL
script:
- pytest tests/integration/
build:
stage: build
# Здесь прокси не задан — прямое подключение
script:
- npm ci && npm run build
Self-hosted GitLab Runner: настройка прокси на уровне раннера
Если вы используете собственный GitLab Runner, можно задать прокси глобально в конфигурации раннера. Откройте файл /etc/gitlab-runner/config.toml и добавьте в секцию [runners.env]:
[[runners]]
name = "my-runner"
url = "https://gitlab.com/"
token = "TOKEN"
executor = "docker"
environment = [
"HTTP_PROXY=http://user:[email protected]:port",
"HTTPS_PROXY=http://user:[email protected]:port",
"NO_PROXY=localhost,127.0.0.1"
]
Это удобно, когда все пайплайны на данном раннере должны использовать прокси — не нужно прописывать его в каждом .gitlab-ci.yml.
Настройка прокси в Jenkins
Jenkins — самый гибкий из трёх инструментов, но и самый сложный в настройке. Прокси здесь можно задать на нескольких уровнях: глобально для всего Jenkins, для конкретного Pipeline или для отдельного шага.
Способ 1: Глобальные настройки прокси в Jenkins
- Откройте Manage Jenkins → System
- Найдите раздел HTTP Proxy Configuration
- Заполните поля: Server, Port, Username, Password
- В поле No Proxy Host укажите внутренние адреса через запятую
- Нажмите Test URL для проверки и сохраните
Эта настройка влияет на загрузку плагинов и обновлений самого Jenkins, но не автоматически передаётся в среду выполнения пайплайнов. Для пайплайнов нужна отдельная конфигурация.
Способ 2: Прокси в Declarative Pipeline через environment
pipeline {
agent any
environment {
HTTP_PROXY = credentials('proxy-url-credential')
HTTPS_PROXY = credentials('proxy-url-credential')
NO_PROXY = 'localhost,127.0.0.1,internal.company.com'
}
stages {
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Integration Tests') {
steps {
sh 'pytest tests/integration/'
}
}
stage('Deploy') {
steps {
sh '''
curl -X POST https://api.external-service.com/deploy \
-H "Authorization: Bearer ${DEPLOY_TOKEN}" \
-d "version=${GIT_COMMIT}"
'''
}
}
}
}
Шаг 3: Добавьте учётные данные прокси в Jenkins Credentials
- Откройте Manage Jenkins → Credentials → System → Global credentials
- Нажмите Add Credentials
- Тип: Secret text
- ID:
proxy-url-credential - Secret:
http://user:[email protected]:port
Способ 3: Прокси через JVM-параметры для Java-проектов
Если ваш пайплайн строит Java-проект (Maven, Gradle), системные переменные окружения могут не работать — JVM использует собственные системные свойства. Добавьте их в JAVA_OPTS:
environment {
JAVA_OPTS = '-Dhttps.proxyHost=proxy.host -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user -Dhttps.proxyPassword=password -Dhttp.nonProxyHosts=localhost|127.0.0.1|*.internal.com'
}
Прокси внутри Docker-контейнеров в пайплайне
Большинство современных CI/CD пайплайнов запускают шаги внутри Docker-контейнеров. Передача прокси в контейнер — отдельная задача, которая решается несколькими способами.
Передача прокси через --build-arg при сборке образа
Если прокси нужен только во время сборки Docker-образа (например, для установки пакетов внутри Dockerfile), используйте build arguments:
# В .github/workflows/build.yml или .gitlab-ci.yml
docker build \
--build-arg HTTP_PROXY=$HTTP_PROXY \
--build-arg HTTPS_PROXY=$HTTPS_PROXY \
--build-arg NO_PROXY=$NO_PROXY \
-t myapp:latest .
# В Dockerfile
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
ENV NO_PROXY=$NO_PROXY
RUN apt-get update && apt-get install -y curl
RUN npm ci
⚠️ Важно: безопасность при сборке образов
Переменные, заданные через ARG и ENV в Dockerfile, сохраняются в метаданных образа и видны через docker inspect. Если прокси требует аутентификации, убедитесь, что готовый образ не публикуется в публичный реестр — иначе учётные данные окажутся в открытом доступе.
Глобальная настройка Docker daemon для прокси
На self-hosted раннерах можно настроить прокси для всего Docker daemon — тогда все контейнеры автоматически получат прокси без изменений в Dockerfile:
# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://user:[email protected]:port"
Environment="HTTPS_PROXY=http://user:[email protected]:port"
Environment="NO_PROXY=localhost,127.0.0.1,registry.internal.com"
# Применить изменения:
# systemctl daemon-reload
# systemctl restart docker
Безопасность: как хранить учётные данные прокси
Учётные данные прокси — это такие же секреты, как API-ключи или пароли от баз данных. Их утечка означает, что кто угодно сможет использовать ваш прокси за ваш счёт. Вот правила безопасного хранения:
Чек-лист безопасности
- ✅ Никогда не вписывайте логин/пароль прокси прямо в YAML-файлы пайплайна
- ✅ Используйте Masked variables в GitLab и Encrypted secrets в GitHub — они скрываются в логах
- ✅ В Jenkins используйте тип Secret text или Username with password в Credentials Store
- ✅ Добавьте
NO_PROXYдля внутренних адресов — трафик к своей инфраструктуре не должен идти через прокси - ✅ Регулярно ротируйте пароли прокси — обновляйте только в хранилище секретов, не меняя код пайплайна
- ✅ Используйте IP-аутентификацию прокси (whitelist IP раннера) там, где это поддерживается — это надёжнее пароля
- ✅ Проверяйте логи прокси на предмет необычной активности
Формат URL прокси: что куда вставлять
| Протокол | Формат URL | Когда использовать |
|---|---|---|
| HTTP | http://user:pass@host:port |
Большинство инструментов, npm, pip, curl |
| HTTPS | https://user:pass@host:port |
Зашифрованное соединение с прокси-сервером |
| SOCKS5 | socks5://user:pass@host:port |
Нестандартные порты, UDP-трафик, максимальная совместимость |
Частые ошибки и как их исправить
Даже после правильной настройки могут возникнуть проблемы. Вот самые распространённые ошибки и их решения:
Ошибка: Proxy Authentication Required (407)
Причина: Неверный логин или пароль, либо они не передаются инструментом.
Решение: Проверьте формат URL — спецсимволы в пароле нужно URL-энкодить. Например, p@ss#word → p%40ss%23word. Также убедитесь, что переменная окружения действительно передаётся в шаг — выведите её через echo $HTTP_PROXY (первые символы) для проверки.
Ошибка: SSL Certificate Verification Failed
Причина: Прокси выполняет SSL-инспекцию (MITM) и подменяет сертификат. Клиент не доверяет сертификату прокси.
Решение: Добавьте корневой сертификат прокси в доверенные. Для curl: --cacert /path/to/proxy-ca.crt. Для npm: npm config set cafile /path/to/proxy-ca.crt. Либо используйте прокси без SSL-инспекции — для CI/CD это предпочтительнее.
Ошибка: Connection Timeout через прокси
Причина: Прокси-сервер недоступен с IP раннера, или порт заблокирован firewall.
Решение: Проверьте доступность прокси командой nc -zv proxy.host port в шаге пайплайна. Убедитесь, что IP раннера добавлен в whitelist прокси-провайдера (если используется IP-аутентификация). Для облачных раннеров GitHub Actions IP-диапазоны публикуются в meta.github.com.
Ошибка: Инструмент игнорирует переменные HTTP_PROXY
Причина: Некоторые инструменты (особенно Java-based) не читают системные переменные окружения.
Решение: Используйте нативную настройку прокси для конкретного инструмента (см. таблицу выше). Для Java добавьте JVM-свойства через JAVA_OPTS. Для curl используйте флаг -x http://proxy:port явно.
Ошибка: Внутренние сервисы тоже идут через прокси
Причина: Переменная NO_PROXY не задана или задана неправильно.
Решение: Укажите все внутренние домены и IP в NO_PROXY. Используйте wildcard для доменов: NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.internal.company.com. Обратите внимание: некоторые инструменты поддерживают CIDR-нотацию, другие — только точные домены.
Заключение
Настройка прокси в CI/CD пайплайне — это не разовая задача, а часть правильной архитектуры автоматизации. Мы разобрали три основных инструмента: GitHub Actions (через Secrets и переменные окружения), GitLab CI (через Variables с маскированием) и Jenkins (через Credentials Store и Declarative Pipeline). Ключевые принципы одинаковы для всех: никогда не хранить учётные данные в коде, использовать NO_PROXY для внутренних адресов и выбирать тип прокси под конкретную задачу.
Выбор правильного типа прокси критически важен для стабильности пайплайна. Для скачивания зависимостей и обращений к стандартным API достаточно быстрых прокси дата-центров. Если же ваш пайплайн проводит интеграционное тестирование на реальных сайтах, работает с рекламными платформами (Facebook Ads API, TikTok Ads API) или обращается к маркетплейсам — используйте резидентные прокси: их IP воспринимаются как обычный пользовательский трафик и крайне редко попадают под блокировки или rate limiting.
Главное правило: тестируйте прокси отдельным шагом в начале пайплайна — это позволит быстро диагностировать проблемы и не тратить время на поиск ошибки в конце долгой сборки. Добавьте шаг curl -v https://api.ipify.org сразу после настройки прокси — он покажет IP, с которого уходят запросы, и подтвердит, что проксирование работает корректно.