GitHub Actionsは強力な自動化ツールです。テストを実行し、アプリケーションをデプロイし、データを収集し、他の多くのタスクを実行します。しかし、ワークフローが外部リソース(マーケットプレイス、広告プラットフォーム、海外のAPI)にアクセスし始めると、すぐに地理的制限やIP制限に直面します。解決策は1つ:パイプラインに直接プロキシを接続することです。
GitHub Actionsでプロキシが必要な理由:実際のシナリオ
多くのチームは、コードのデプロイだけでなく、ビジネスの自動化にもGitHub Actionsを使用しています。競合の価格モニタリング、マーケットプレイスからのデータ収集、広告アカウントの自動チェック、異なる地域からのウェブサイトのテストなどです。これらのタスクには共通の問題があります。GitHub ActionsのランナーはMicrosoft Azureの固定IPを持っており、多くのサービスがこれをブロックまたは制限します。
プロキシが必要な具体的な状況は以下の通りです:
- Wildberries、Ozon、Avitoのデータ収集 — これらのプラットフォームは、クラウドプロバイダーのIP範囲をブラックリストに登録しています。GitHub Actionsのランナーからのリクエストは、2〜3回の試行でブロックされるか、キャプチャが表示されます。
- 地理的ターゲティングテスト — マーケティング担当者やQAエンジニアは、モスクワ、ベルリン、ニューヨークのユーザー向けにサイトや広告がどのように見えるかを確認します。プロキシなしでは、ランナーは常に1つの地域のコンテンツしか「見る」ことができません。
- 地域制限のあるAPIとの連携 — 一部のAPI(例えば、特定の設定の地域版Google AdsやFacebook Marketing API)は、リクエストの地理的位置に応じて異なるデータを返します。
- 競合のモニタリング — 自動的な価格、プロモーション、品揃えの収集は、繰り返しのデータセンターIPによって容易に検出されるため、定期的なリクエストが必要です。
- 広告チェックの自動化 — アービトラージ担当者やパフォーマンスマーケティング担当者は、CI/CD内のスクリプトを介して広告のステータス、残高、メトリクスの自動チェックを実行します。
- 外部サービスとの統合テスト — 一部のサービスは、セキュリティ上の理由からAzure範囲からのリクエストをブロックし、テストが説明なしに失敗します。
これらのすべてのケースで、プロキシは根本的な問題を解決します。ワークフローは、Microsoftのクラウドサーバーからではなく、必要な都市の通常のユーザーからのリクエストのように見えるようになります。
GitHub Actionsがネットワークとどのように連携するか
プロキシを設定する前に、GitHub Actionsのネットワークアーキテクチャを理解することが重要です。標準のubuntu-latestランナーでワークフローを実行すると、タスクはMicrosoft Azureのインフラストラクチャ内の仮想マシンで実行されます。このようなマシンには、Azureの範囲からのパブリックIPがあり、外部サービスはこのIPを確認します。
GitHub Actionsのネットワークの主な特徴:
- 各実行時にIPが変更される — しかし、知られているAzureの範囲内にとどまります。
- プロキシのネイティブサポートはない — GitHubはトラフィックのプロキシングのためのネイティブメカニズムを提供していません。
- 環境変数はグローバルに機能する —
HTTP_PROXYをジョブレベルで設定すると、そのジョブ内のすべてのステップがプロキシを使用します。 - セルフホストランナー — 自分のサーバーでランナーを実行する代替手段です。この場合、プロキシはワークフローではなくサーバーレベルで設定されます。
ほとんどのタスクにとって、最適なアプローチは、ワークフローファイル内で環境変数を介してプロキシを設定することです(.github/workflows/your-workflow.yml)。これは、curl、wget、Python requests、Node.js http、Go net/httpなどのほとんどのツールで機能する汎用的な方法です。
CI/CD用のプロキシの種類を選ぶには
プロキシの種類の選択は、タスクによって異なります。CI/CDパイプラインには3つのオプションがあり、それぞれに特有のニッチがあります:
| プロキシの種類 | どのようなタスクに使用するか | 速度 | 信頼性のレベル |
|---|---|---|---|
| レジデンシャルプロキシ | 保護されたサイトのデータ収集、地理的ターゲティング、マーケットプレイスのモニタリング | 中程度 | 高い — 実際の家庭用IP |
| モバイルプロキシ | モバイル版のテスト、ソーシャルメディアとの連携、Facebook/TikTok API | 中程度 | 最大 — キャリアのIP |
| データセンタープロキシ | 統合テスト、保護されていないAPIへのリクエスト、高負荷 | 高い | 中程度 |
実践的なルール:ワークフローがWildberries、Ozon、または他のボット対策があるマーケットプレイスをパースする場合は、レジデンシャルプロキシを使用してください。Facebook AdsやTikTok Adsの広告アカウントをテストする場合は、モバイルプロキシを使用します。簡単な統合テストやオープンAPIへのリクエストには、データセンタープロキシで十分です。これらはより速く、安価です。
💡 プロトコルについて重要なこと
GitHub Actionsでは、HTTP/HTTPSプロキシを使用することが推奨されます。これらは、追加の設定なしでほとんどのツールでサポートされています。SOCKS5も機能しますが、各ツールで明示的に指定する必要があります。プロバイダーが両方のプロトコルをサポートしている場合は、HTTPから始めてください。
環境変数を使用したプロキシの設定
GitHub Actionsでプロキシを接続する最も汎用的な方法は、標準の環境変数HTTP_PROXY、HTTPS_PROXY、およびNO_PROXYを設定することです。ほとんどのコマンドラインツールやプログラミング言語は、これらを自動的に認識します。
プロキシを使用したワークフローの基本構造は次のとおりです:
name: プロキシを使用したワークフロー
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: リポジトリをチェックアウト
uses: actions/checkout@v4
- name: 現在のIPをチェック(確認用)
run: curl -s https://api.ipify.org
- name: メインスクリプトを実行
run: python scripts/scraper.py
NO_PROXYブロックに注意してください。ここには、トラフィックをプロキシしない必要があるアドレスを追加する必要があります。少なくともlocalhostと127.0.0.1を追加する必要があります。また、リポジトリに対する操作(チェックアウト、プッシュ)が直接行われるように、github.comを追加することをお勧めします。
認証なしのプロキシ(IPとポートのみ)の場合、形式は簡略化されます:
env:
HTTP_PROXY: http://203.0.113.10:8080
HTTPS_PROXY: http://203.0.113.10:8080
NO_PROXY: localhost,127.0.0.1
SOCKS5プロキシの場合、URLのスキームだけが変更されます:
env:
HTTP_PROXY: socks5://user:password@proxy-host:1080
HTTPS_PROXY: socks5://user:password@proxy-host:1080
curl、wget、HTTPリクエストのためのプロキシ
環境変数がジョブレベルで設定されている場合(上記のように)、curlとwgetは自動的にそれらを認識します。しかし、特定のステップやデバッグ時にプロキシを明示的に指定する必要がある場合もあります。
curlでのプロキシの明示的な指定:
- name: プロキシを使用してデータを取得
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
# プロキシを介した確認
curl -x http://${{ secrets.PROXY_USER }}:${{ secrets.PROXY_PASS }}@${{ secrets.PROXY_HOST }}:${{ secrets.PROXY_PORT }} \
-s https://api.ipify.org?format=json
wgetの場合:
- name: プロキシ経由でwgetでダウンロード
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
デバッグ用の便利なステップは、ワークフローの最初にIPアドレスを確認することです。プロキシが正しく機能している場合、AzureではなくプロキシサーバーのIPが表示されます:
- name: プロキシがアクティブであることを確認
run: |
echo "=== プロキシなしのIP ==="
curl -s --noproxy '*' https://api.ipify.org || echo "直接リクエストが失敗しました"
echo ""
echo "=== プロキシ経由のIP ==="
curl -s https://api.ipify.org
ワークフロー内のPythonスクリプトでのプロキシ
PythonはCI/CDでスクリプトを書くための最も人気のある言語の1つです。requestsライブラリは、設定されている場合、環境変数HTTP_PROXYとHTTPS_PROXYを自動的に読み取ります。しかし、より柔軟な管理のためには、プロキシを明示的に渡す方が良いです。
環境変数を介してプロキシを明示的に渡すPythonスクリプトの例:
import os
import requests
# 環境変数からプロキシデータを読み取る
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}',
}
# リクエストでプロキシを使用
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"ステータス: {response.status_code}")
print(f"コンテンツの長さ: {len(response.content)}")
ワークフローファイルでは、変数を個別のシークレットとして渡す必要があります(完全なURLではなく)、スクリプトがそれらを収集できるようにします:
- name: 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
PlaywrightやSeleniumを使用する場合、Pythonでのプロキシの設定は少し異なります:
# 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")
# ... 続くロジック
browser.close()
Node.jsおよびnpmタスクでのプロキシ
Node.jsは自動的にシステム変数HTTP_PROXYを読み取らないため、特別なライブラリを使用するか、プロキシを明示的に設定する必要があります。最も便利なオプションは、https-proxy-agentパッケージまたはaxiosを使用してプロキシ設定を行うことです。
// 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(`リクエストが失敗しました: ${error.message}`);
throw error;
}
}
fetchData('https://api.example.com/prices')
.then(data => console.log(JSON.stringify(data, null, 2)))
.catch(() => process.exit(1));
npmコマンド(例えば、npmが企業のプロキシを介してパッケージをダウンロードしようとする場合)の設定は、より簡単です:
- name: 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: 依存関係をインストール
run: npm install
- name: npmプロキシをリセット(使用後にクリア)
run: |
npm config delete proxy
npm config delete https-proxy
GitHub Secretsにおけるプロキシデータの安全な保存
プロキシデータ(ホスト、ポート、ログイン、パスワード)をワークフローファイルにそのまま保存しないでください。これは重大なセキュリティの誤りです。ワークフローファイルはリポジトリに保存され、プロジェクトのすべての参加者に見える可能性があります。
正しいアプローチはGitHub Secretsです。手順は以下の通りです:
- GitHubでリポジトリを開く
- Settings → Secrets and variables → Actionsに移動する
- New repository secretをクリックする
- 4つのシークレットを作成する:
PROXY_HOST、PROXY_PORT、PROXY_USER、PROXY_PASS - ワークフロー内で、
${{ secrets.PROXY_HOST }}の構文を使用してそれらにアクセスする
🔒 追加のセキュリティ対策
- Environment secretsを使用して、異なる環境(ステージング/プロダクション)が異なるプロキシを使用する場合
- Environment protection rulesを使用してシークレットへのアクセスを制限し、プロダクションには手動確認を要求する
- プロキシの資格情報を定期的にローテーションする — 30〜90日ごとにパスワードを変更する
echoを介してシークレットの値をログに出力しない — GitHubは自動的にそれらをマスクしますが、リスクを冒さない方が良いです
ローテーションプロキシを使用している場合(リクエストごとにIPが変更されるか、スケジュールに従って変更される場合)、通常は1つのエンドポイントだけを保存することで十分です — プロキシプロバイダーが自動的にIPプールを管理します。この場合、シークレットにはローテーションゲートウェイのホストとポートのみが含まれます。
プロキシのローテーションとエラーハンドリング
高品質のプロキシでも時々問題が発生します。IPが一時的に禁止されることがあり、セッションが切断されることがあり、サーバーが応答しないことがあります。自動的に監視されないCI/CDパイプラインでは、これらの状況を考慮することが重要です。
戦略1:同じプロキシでの再試行
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"試行 {attempt + 1} が失敗しました: {e}")
if attempt < max_retries - 1:
print(f"{delay}秒後に再試行します...")
time.sleep(delay)
delay *= 2 # 指数的遅延
raise Exception(f"{url}のすべての{max_retries}回の試行が失敗しました")
戦略2:プロキシのリストと切り替え
複数のプロキシサーバーがある場合、それらのリストを1つのシークレットに(カンマで区切って)保存し、エラー時に切り替えることができます:
import os
import requests
import random
# シークレットPROXY_LISTには次のように含まれます:"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) # ランダムな順序
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"プロキシが失敗しました: {e}、次を試みます...")
raise Exception("すべてのプロキシが使い果たされました")
戦略3:ローテーションエンドポイントの使用
最も簡単なオプションは、単一のローテーションゲートウェイを持つプロキシプロバイダーを使用することです。この場合、1つのアドレスに接続し、プロバイダーが自動的にプールから異なるIPを提供します。コード内にローテーションのロジックは必要ありません — 接続の1行だけで十分です。
実際のシナリオ:データ収集、テスト、モニタリング
GitHub Actionsでプロキシを使用しているチームによく見られる3つの具体的なシナリオを考えてみましょう。
シナリオ1:Wildberriesの価格を毎日モニタリング
マーケットプレイスのセラーは、競合の価格を自動的に収集するための設定を行うことがよくあります。ワークフローはスケジュールに従って実行され(例えば、毎朝7:00)、データを収集し、Google Sheetsに保存するか、Telegramに送信します。
name: 毎日の価格モニター
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: Pythonをセットアップ
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: 依存関係をインストール
run: pip install requests beautifulsoup4 gspread
- name: 価格スクレイパーを実行
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: 結果アーティファクトをアップロード
uses: actions/upload-artifact@v4
with:
name: price-data-${{ github.run_id }}
path: output/prices.json
シナリオ2:地理的ターゲティングテスト
マーケティング担当者やQAチームは、異なる都市のユーザー向けにサイトや広告がどのように見えるかを確認するためにプロキシを使用します。特に地域の価格、コンテンツ、リダイレクトの確認に役立ちます。
name: 地理的ターゲットサイトテスト
on:
push:
branches: [main]
pull_request:
jobs:
test-moscow:
runs-on: ubuntu-latest
name: モスクワからのテスト
steps:
- uses: actions/checkout@v4
- name: 地理テストを実行(RU/モスクワプロキシ)
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: ドイツからのテスト
steps:
- uses: actions/checkout@v4
- name: 地理テストを実行(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
シナリオ3:広告アカウントの自動チェック
アービトラージ担当者やパフォーマンスマーケティング担当者は、Facebook Adsの広告アカウントのステータス、残高、メトリクスを自動的にチェックするためにGitHub Actionsを使用することがよくあります。Azure範囲からのFacebook Marketing APIへのリクエストは、追加のセキュリティチェックを引き起こす可能性があるため、プロキシを使用してこれを回避します。
name: 広告アカウントの健康チェック
on:
schedule:
- cron: '*/30 6-22 * * *' # 6時から22時まで30分ごとに
jobs:
check-accounts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Pythonをセットアップ
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: 依存関係をインストール
run: pip install requests
- name: 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
📋 プロキシを使用したワークフローを開始する前のチェックリスト
- ✅ プロキシデータがGitHub Secretsに追加されている(ワークフローファイルには含まれていない)
- ✅
NO_PROXY変数にgithub.comが含まれている - ✅ デバッグ用にIP確認ステップが追加されている
- ✅ エラーハンドリングと再試行ロジックが実装されている
- ✅ プロキシの種類がタスクに適している(保護されたサイトにはレジデンシャルプロキシを使用)
- ✅ エラー通知が設定されている(Telegram、Slack、またはメール)
- ✅ スケジュールを追加する前に、
workflow_dispatchを介して手動でワークフローがテストされている
結論
GitHub Actionsでのプロキシ設定は、正しいアプローチを知っていれば難しくありません。このガイドからの主なポイントは次のとおりです:
- 環境変数
HTTP_PROXY/HTTPS_PROXY— ほとんどのツールでコードを変更せずに機能する汎用的な方法です。 - GitHub Secrets — プロキシの資格情報を保存するための唯一の正しい場所です。
- プロキシの種類が重要: 保護されたマーケットプレイスをパースするにはレジデンシャルIPが必要で、広告プラットフォームにはモバイルプロキシが必要で、単純なAPIリクエストにはデータセンタープロキシが適しています。
- 再試行ロジックは必須 — スケジュールに従って監視されないパイプラインに対して。
- IP確認ステップをワークフローの最初に追加することで、デバッグの時間を節約できます。
GitHub Actionsのワークフローがマーケットプレイス、広告プラットフォーム、またはボット対策のあるサービスと連携している場合は、レジデンシャルプロキシの使用をお勧めします。これらは実際の家庭用ユーザーのIPを持ち、GitHubサーバーのクラウドアドレスに比べてブロックされる可能性が大幅に低くなります。Facebook Ads、TikTok、または他のソーシャルプラットフォームに関連するタスクには、キャリアのIPを持つモバイルプロキシが最適な選択です — これにより、プラットフォームからの信頼性が最大化されます。
```