GitHub Actions é uma poderosa ferramenta de automação: ela executa testes, faz deploy de aplicativos, coleta dados e realiza dezenas de outras tarefas. Mas assim que o workflow começa a acessar recursos externos — marketplaces, plataformas de publicidade, APIs estrangeiras — ele imediatamente se depara com bloqueios geográficos e limites de IP. A solução é simples: conectar um proxy diretamente no pipeline.
Por que usar proxies no GitHub Actions: cenários reais
Muitas equipes usam GitHub Actions não apenas para fazer deploy de código, mas também para automatizar tarefas de negócios: monitoramento de preços de concorrentes, coleta de dados de marketplaces, verificação automática de contas de anúncios e testes de sites de diferentes regiões. Todas essas tarefas têm um problema em comum — o runner do GitHub Actions tem um IP fixo da faixa do Microsoft Azure, e muitos serviços o bloqueiam ou limitam.
Aqui estão situações específicas em que um proxy é indispensável:
- Scraping de Wildberries, Ozon, Avito — essas plataformas já bloquearam faixas de IP de provedores de nuvem. Uma solicitação do runner do GitHub Actions será bloqueada ou receberá um captcha já na 2ª ou 3ª tentativa.
- Testes geotargetizados — profissionais de marketing e engenheiros de QA verificam como o site ou o anúncio aparecem para usuários de Moscovo, Berlim ou Nova Iorque. Sem um proxy, o runner sempre "verá" o conteúdo de uma única região.
- Trabalho com APIs limitadas por região — algumas APIs (por exemplo, versões regionais do Google Ads, Facebook Marketing API com configurações específicas) retornam dados diferentes dependendo da geolocalização da solicitação.
- Monitoramento de concorrentes — a coleta automática de preços, promoções e sortimentos requer solicitações regulares, que são facilmente detectadas por um IP repetido de um data center.
- Automação de verificações de anúncios — arbitradores e profissionais de marketing de performance executam verificações automáticas do status de anúncios, saldos e métricas através de scripts em CI/CD.
- Testes de integração com serviços externos — alguns serviços bloqueiam solicitações de faixas do Azure por motivos de segurança, e os testes simplesmente falham sem explicações.
Em todos esses casos, o proxy resolve o problema de forma radical: o workflow começa a parecer uma solicitação de um usuário comum da cidade desejada, e não de um servidor em nuvem da Microsoft.
Como o GitHub Actions funciona com a rede
Antes de configurar um proxy, é importante entender a arquitetura da rede no GitHub Actions. Quando você executa um workflow em um runner padrão ubuntu-latest, a tarefa é executada em uma máquina virtual na infraestrutura do Microsoft Azure. Cada uma dessas máquinas tem um IP público da faixa do Azure — e é esse IP que os serviços externos veem.
Características-chave da rede no GitHub Actions:
- O IP muda a cada execução — mas permanece dentro das faixas conhecidas do Azure, que são facilmente detectáveis.
- Não há suporte embutido para proxies — o GitHub não fornece um mecanismo nativo para proxy de tráfego.
- Variáveis de ambiente funcionam globalmente — se você definir
HTTP_PROXYno nível do job, todos os passos dentro desse job usarão o proxy. - Runners auto-hospedados — uma alternativa em que você executa o runner em seu próprio servidor. Nesse caso, o proxy é configurado no nível do servidor, e não do workflow.
Para a maioria das tarefas, a abordagem ideal é configurar o proxy através de variáveis de ambiente diretamente no arquivo do workflow (.github/workflows/seu-workflow.yml). Este é um método universal que funciona para a maioria das ferramentas: curl, wget, Python requests, Node.js http, Go net/http e outras.
Qual tipo de proxy escolher para CI/CD
A escolha do tipo de proxy depende da tarefa. Para pipelines CI/CD, três opções são relevantes, e cada uma tem seu nicho:
| Tipo de proxy | Para quais tarefas | Velocidade | Nível de confiança |
|---|---|---|---|
| Proxies residenciais | Scraping de sites protegidos, geotargeting, monitoramento de marketplaces | Média | Alta — IPs residenciais reais |
| Proxies móveis | Testes de versões móveis, trabalho com redes sociais, Facebook/TikTok API | Média | Máxima — IPs de operadoras |
| Proxies de data center | Testes de integração, requisições a APIs não protegidas, alta carga | Alta | Média |
Regra prática: se seu workflow faz scraping de Wildberries, Ozon ou outros marketplaces com proteção contra bots — use proxies residenciais. Se você está testando contas de anúncios do Facebook Ads ou TikTok Ads — use proxies móveis. Para testes de integração simples e requisições a APIs abertas, proxies de data center são suficientes: eles são mais rápidos e mais baratos.
💡 Importante sobre protocolos
Para GitHub Actions, é preferível usar proxies HTTP/HTTPS — eles são suportados pela maioria das ferramentas sem configurações adicionais. SOCKS5 também funciona, mas requer especificação explícita em cada ferramenta. Se seu provedor suporta ambos os protocolos — comece com HTTP.
Configuração de proxy através de variáveis de ambiente
A maneira mais universal de conectar um proxy no GitHub Actions é definir as variáveis de ambiente padrão HTTP_PROXY, HTTPS_PROXY e NO_PROXY. A maioria das ferramentas de linha de comando e linguagens de programação as reconhece automaticamente.
A estrutura básica de um workflow com proxy é assim:
name: Workflow com Proxy
on:
schedule:
- cron: '0 9 * * *'
workflow_dispatch:
jobs:
scrape-data:
runs-on: ubuntu-latest
env:
HTTP_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
HTTPS_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
NO_PROXY: localhost,127.0.0.1,github.com
steps:
- name: Checkout do repositório
uses: actions/checkout@v4
- name: Verificar IP atual (para verificação)
run: curl -s https://api.ipify.org
- name: Executar script principal
run: python scripts/scraper.py
Preste atenção ao bloco NO_PROXY — nele você deve adicionar os endereços que não precisam ter o tráfego proxy. No mínimo, isso inclui localhost e 127.0.0.1. Também é recomendável adicionar github.com, para que as operações com o repositório (checkout, push) sejam feitas diretamente.
Se o proxy não requer autenticação (apenas IP e porta), o formato se simplifica:
env:
HTTP_PROXY: http://203.0.113.10:8080
HTTPS_PROXY: http://203.0.113.10:8080
NO_PROXY: localhost,127.0.0.1
Para proxies SOCKS5, apenas o esquema na URL muda:
env:
HTTP_PROXY: socks5://user:password@proxy-host:1080
HTTPS_PROXY: socks5://user:password@proxy-host:1080
Proxy para curl, wget e requisições HTTP no shell
Se as variáveis de ambiente estão definidas no nível do job (como mostrado acima), curl e wget as reconhecerão automaticamente. Mas às vezes é necessário passar o proxy explicitamente — por exemplo, para um passo específico ou durante a depuração.
Especificação explícita do proxy no curl:
- name: Buscar dados com proxy
run: |
curl -x http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }} \
-s \
-o output.json \
https://api.example.com/data
# Verificação através do proxy
curl -x http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }} \
-s https://api.ipify.org?format=json
Para wget:
- name: Baixar com wget via proxy
run: |
wget -e "https_proxy=http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}" \
-q \
-O data.html \
https://target-site.com/page
Um passo útil para depuração — adicione no início do workflow uma verificação do endereço IP. Se o proxy estiver funcionando corretamente, você verá o IP do servidor proxy, e não do Azure:
- name: Verificar se o proxy está ativo
run: |
echo "=== IP sem proxy ==="
curl -s --noproxy '*' https://api.ipify.org || echo "Solicitação direta falhou"
echo ""
echo "=== IP através do proxy ==="
curl -s https://api.ipify.org
Proxy em scripts Python dentro do workflow
Python é uma das linguagens mais populares para scripts em CI/CD. A biblioteca requests lê automaticamente as variáveis de ambiente HTTP_PROXY e HTTPS_PROXY, se estiverem definidas. Mas para um controle mais flexível, é melhor passar o proxy explicitamente.
Exemplo de script Python com passagem explícita do proxy através de variáveis de ambiente:
import os
import requests
# Lendo dados do proxy das variáveis de ambiente
proxy_host = os.environ.get('PROXY_HOST')
proxy_port = os.environ.get('PROXY_PORT')
proxy_user = os.environ.get('PROXY_USER')
proxy_pass = os.environ.get('PROXY_PASS')
proxies = {
'http': f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}',
'https': f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}',
}
# Usando o proxy na requisição
response = requests.get(
'https://www.wildberries.ru/catalog/123456/detail.aspx',
proxies=proxies,
timeout=30,
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
)
print(f"Status: {response.status_code}")
print(f"Comprimento do conteúdo: {len(response.content)}")
No arquivo do workflow, você deve passar as variáveis como segredos separados (não como uma URL completa), para que o script possa coletá-las:
- name: Executar scraper Python
env:
PROXY_HOST: ${{ secrets.PROXY_HOST }}
PROXY_PORT: ${{ secrets.PROXY_PORT }}
PROXY_USER: ${{ secrets.PROXY_USER }}
PROXY_PASS: ${{ secrets.PROXY_PASS }}
run: python scripts/scraper.py
Para trabalhar com Playwright ou Selenium em Python, a configuração do proxy é um pouco diferente:
# Playwright
from playwright.sync_api import sync_playwright
import os
proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@{os.environ['PROXY_HOST']}:{os.environ['PROXY_PORT']}"
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": proxy_url
}
)
page = browser.new_page()
page.goto("https://target-site.com")
# ... lógica adicional
browser.close()
Proxy em Node.js e tarefas npm
Node.js não lê automaticamente as variáveis de sistema HTTP_PROXY — você precisa usar bibliotecas especiais ou configurar o proxy explicitamente. A opção mais conveniente é o pacote https-proxy-agent ou axios com configuração de proxy.
// Usando axios
const axios = require('axios');
const proxyConfig = {
host: process.env.PROXY_HOST,
port: parseInt(process.env.PROXY_PORT),
auth: {
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS
}
};
async function fetchData(url) {
try {
const response = await axios.get(url, {
proxy: proxyConfig,
timeout: 30000,
headers: {
'User-Agent': 'Mozilla/5.0 (compatible; MyBot/1.0)'
}
});
return response.data;
} catch (error) {
console.error(`Solicitação falhou: ${error.message}`);
throw error;
}
}
fetchData('https://api.example.com/prices')
.then(data => console.log(JSON.stringify(data, null, 2)))
.catch(() => process.exit(1));
Para comandos npm (por exemplo, se o npm tentar baixar pacotes através de um proxy corporativo), a configuração é mais simples:
- name: Configurar proxy npm
run: |
npm config set proxy http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
npm config set https-proxy http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
- name: Instalar dependências
run: npm install
- name: Resetar proxy npm (limpar após uso)
run: |
npm config delete proxy
npm config delete https-proxy
Armazenamento seguro de dados de proxy em GitHub Secrets
Nunca armazene dados de proxy (host, porta, login, senha) diretamente no arquivo do workflow em texto claro. Isso é um erro grave de segurança: os arquivos do workflow são armazenados no repositório e podem ser visíveis para todos os participantes do projeto ou até mesmo publicamente.
A abordagem correta é usar GitHub Secrets. Aqui está um guia passo a passo:
- Abra o repositório no GitHub
- Vá para Settings → Secrets and variables → Actions
- Clique em New repository secret
- Crie quatro segredos:
PROXY_HOST,PROXY_PORT,PROXY_USER,PROXY_PASS - No workflow, acesse-os através da sintaxe
${{ secrets.PROXY_HOST }}
🔒 Medidas adicionais de segurança
- Use Environment secrets em vez de Repository secrets, se diferentes ambientes (staging/production) usarem proxies diferentes
- Limite o acesso aos segredos através de Environment protection rules — exija confirmação manual para produção
- Rotacione regularmente as credenciais do proxy — altere as senhas a cada 30–90 dias
- Não exiba os valores dos segredos nos logs através de
echo— o GitHub os mascara automaticamente, mas é melhor não arriscar
Se você estiver usando proxies rotativos (quando o IP muda a cada solicitação ou em um cronograma), muitas vezes é suficiente armazenar apenas um endpoint — o provedor de proxy gerencia o pool de IPs. Nesse caso, os segredos conterão apenas um host e a porta do gateway de rotação.
Rotação de proxies e tratamento de erros no pipeline
Mesmo proxies de alta qualidade podem falhar às vezes: o IP pode ser temporariamente banido, a sessão pode ser interrompida, o servidor pode não responder. Para pipelines CI/CD que funcionam automaticamente sem supervisão, é importante prever o tratamento dessas situações.
Estratégia 1: Retry com o mesmo proxy
import requests
import time
import os
def fetch_with_retry(url, max_retries=3, delay=5):
proxies = {
'http': f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@{os.environ['PROXY_HOST']}:{os.environ['PROXY_PORT']}",
'https': f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@{os.environ['PROXY_HOST']}:{os.environ['PROXY_PORT']}",
}
for attempt in range(max_retries):
try:
response = requests.get(url, proxies=proxies, timeout=30)
response.raise_for_status()
return response
except requests.exceptions.RequestException as e:
print(f"Tentativa {attempt + 1} falhou: {e}")
if attempt < max_retries - 1:
print(f"Tentando novamente em {delay} segundos...")
time.sleep(delay)
delay *= 2 # Atraso exponencial
raise Exception(f"Todas as {max_retries} tentativas falharam para {url}")
Estratégia 2: Lista de proxies com alternância
Se você tiver vários servidores proxy, pode armazenar a lista deles em um único segredo (separados por vírgula) e alternar em caso de erro:
import os
import requests
import random
# O segredo PROXY_LIST contém: "host1:port1:user1:pass1,host2:port2:user2:pass2"
proxy_list_raw = os.environ.get('PROXY_LIST', '').split(',')
def parse_proxy(proxy_str):
parts = proxy_str.strip().split(':')
if len(parts) == 4:
host, port, user, password = parts
return {
'http': f'http://{user}:{password}@{host}:{port}',
'https': f'http://{user}:{password}@{host}:{port}',
}
return None
proxies = [p for p in [parse_proxy(raw) for raw in proxy_list_raw] if p]
def fetch_with_proxy_rotation(url):
random.shuffle(proxies) # Ordem aleatória
for proxy in proxies:
try:
response = requests.get(url, proxies=proxy, timeout=20)
if response.status_code == 200:
return response
except Exception as e:
print(f"Proxy falhou: {e}, tentando o próximo...")
raise Exception("Todos os proxies foram esgotados")
Estratégia 3: Uso de endpoint rotativo
A opção mais simples é usar um provedor de proxy com um único gateway rotativo. Nesse caso, você se conecta a um único endereço, e o provedor automaticamente fornece diferentes IPs do pool. Nenhuma lógica de rotação é necessária no código — basta uma linha de conexão.
Cenários reais: scraping, testes, monitoramento de preços
Vamos considerar três cenários específicos que são mais comuns entre equipes que usam GitHub Actions com proxies.
Cenário 1: Monitoramento diário de preços no Wildberries
Vendedores de marketplaces frequentemente configuram a coleta automática de preços de concorrentes. O workflow é acionado em um cronograma (por exemplo, todas as manhãs às 7:00), coleta dados e os salva no Google Sheets ou envia para o Telegram.
name: Monitor de Preços Diário
on:
schedule:
- cron: '0 4 * * *' # 07:00 MSK (UTC+3)
jobs:
monitor-prices:
runs-on: ubuntu-latest
env:
HTTP_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
HTTPS_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
NO_PROXY: github.com,api.github.com
steps:
- uses: actions/checkout@v4
- name: Configurar Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Instalar dependências
run: pip install requests beautifulsoup4 gspread
- name: Executar scraper de preços
env:
GOOGLE_SHEETS_KEY: ${{ secrets.GOOGLE_SHEETS_KEY }}
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
run: python scripts/price_monitor.py
- name: Fazer upload do artefato de resultados
uses: actions/upload-artifact@v4
with:
name: price-data-${{ github.run_id }}
path: output/prices.json
Cenário 2: Teste geotargetizado do site
Profissionais de marketing e equipes de QA usam proxies para verificar como o site ou o anúncio aparecem para usuários de diferentes cidades. Isso é especialmente relevante para verificar preços regionais, conteúdo e redirecionamentos.
name: Testes de Site Geotargetizados
on:
push:
branches: [main]
pull_request:
jobs:
test-moscow:
runs-on: ubuntu-latest
name: Teste de Moscovo
steps:
- uses: actions/checkout@v4
- name: Executar testes geográficos (proxy RU/Moscovo)
env:
HTTP_PROXY: http://${{ secrets.PROXY_RU_USER }}:${{ secrets.PROXY_RU_PASS }}@${{ secrets.PROXY_RU_HOST }}:${{ secrets.PROXY_RU_PORT }}
HTTPS_PROXY: http://${{ secrets.PROXY_RU_USER }}:${{ secrets.PROXY_RU_PASS }}@${{ secrets.PROXY_RU_HOST }}:${{ secrets.PROXY_RU_PORT }}
run: |
python tests/geo_test.py --region=RU --city=Moscow
test-germany:
runs-on: ubuntu-latest
name: Teste da Alemanha
steps:
- uses: actions/checkout@v4
- name: Executar testes geográficos (proxy DE)
env:
HTTP_PROXY: http://${{ secrets.PROXY_DE_USER }}:${{ secrets.PROXY_DE_PASS }}@${{ secrets.PROXY_DE_HOST }}:${{ secrets.PROXY_DE_PORT }}
HTTPS_PROXY: http://${{ secrets.PROXY_DE_USER }}:${{ secrets.PROXY_DE_PASS }}@${{ secrets.PROXY_DE_HOST }}:${{ secrets.PROXY_DE_PORT }}
run: |
python tests/geo_test.py --region=DE
Cenário 3: Verificação automática de contas de anúncios
Arbitradores e profissionais de marketing de performance frequentemente usam GitHub Actions para verificar automaticamente o status das contas de anúncios do Facebook Ads, saldos e métricas. Solicitações à Facebook Marketing API de faixas do Azure podem acionar verificações de segurança adicionais — o proxy ajuda a contornar isso.
name: Verificação de Saúde da Conta de Anúncios
on:
schedule:
- cron: '*/30 6-22 * * *' # A cada 30 minutos das 6 às 22 MSK
jobs:
check-accounts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configurar Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Instalar dependências
run: pip install requests
- name: Verificar contas do Facebook Ads
env:
HTTP_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
HTTPS_PROXY: http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }}
FB_ACCESS_TOKEN: ${{ secrets.FB_ACCESS_TOKEN }}
ACCOUNT_IDS: ${{ secrets.FB_ACCOUNT_IDS }}
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
run: python scripts/check_fb_accounts.py
📋 Checklist antes de executar o workflow com proxy
- ✅ Dados do proxy adicionados ao GitHub Secrets (não no arquivo do workflow)
- ✅ Variáveis
NO_PROXYincluemgithub.com - ✅ Passo de verificação de IP adicionado para depuração
- ✅ Tratamento de erros e lógica de retry implementados
- ✅ Tipo de proxy corresponde à tarefa (residenciais para sites protegidos)
- ✅ Notificações de erro configuradas (Telegram, Slack ou email)
- ✅ Workflow testado manualmente através de
workflow_dispatchantes de adicionar o cronograma
Conclusão
Configurar um proxy no GitHub Actions não é uma tarefa difícil se você souber a abordagem correta. As principais conclusões deste guia são:
- Variáveis de ambiente
HTTP_PROXY/HTTPS_PROXY— uma maneira universal que funciona para a maioria das ferramentas sem alteração de código. - GitHub Secrets — o único lugar correto para armazenar credenciais de proxy.
- O tipo de proxy é importante: para scraping de marketplaces protegidos, são necessários IPs residenciais, para plataformas de anúncios — móveis, para requisições simples de API, proxies de data center são suficientes.
- Lógica de retry é obrigatória para pipelines que funcionam sem supervisão em um cronograma.
- Um passo de verificação de IP no início do workflow economizará horas de depuração.
Se seu workflow do GitHub Actions trabalha com marketplaces, plataformas de anúncios ou qualquer serviço com proteção contra bots, recomendamos usar proxies residenciais — eles têm IPs reais de usuários domésticos e raramente causam bloqueios em comparação com endereços em nuvem dos servidores do GitHub. Para tarefas relacionadas ao Facebook Ads, TikTok ou outras plataformas sociais, a escolha ideal são proxies móveis com IPs de operadoras — eles oferecem o máximo nível de confiança por parte das plataformas.
```