GitHub の clone や release のダウンロードが遅い、Docker Hub のイメージ取得が途中で止まる、npm install がタイムアウトする——これらは、開発用PCから海外のサービスへ接続する経路が混雑しているときに起こりやすい問題です。ただし、クライアントでVPNをオンにするだけでは十分ではありません。ブラウザーは動いているのに、Git、Docker、Node.js のパッケージマネージャーは別のプロキシ設定や別のネットワーク経路を使うことがあるためです。
本記事では、ローカル開発環境とCI/CDの両方を対象に、GitHub、Docker Hub、npm Registryを用途別に設定する考え方を整理します。重要なのは、すべての通信を一律に変更することではありません。必要な開発ツールだけにプロキシを適用し、認証情報をログへ出さず、問題が起きたときに元の設定へ戻せる状態を保つことです。
100+
対応国・地域
180+
利用可能な回線
5
対応プラットフォーム
30日
無理由退款
なぜGitHub・Docker・npmだけ遅くなるのか
開発ツールの通信が遅い原因は、単純な回線速度だけではありません。GitHubのリポジトリ本体、Git LFSの大きなファイル、Releaseアセット、Docker Hubのレイヤー、npm Registryのメタデータとパッケージは、それぞれ接続先や転送方式が異なります。同じドメインを使っているように見えても、実際にはCDN、認証サーバー、オブジェクトストレージなどへリダイレクトされる場合があります。
さらに、Gitはターミナルの環境変数や独自の設定を参照し、DockerはCLIとDocker daemonが別プロセスとして動作します。Docker DesktopではGUI側の設定がdaemonに適用されますが、LinuxのDocker Engineではsystemdサービスにプロキシを設定しなければ、シェルでexportしたHTTP_PROXYがpull処理に反映されないことがあります。npmも環境変数、npm config、プロジェクト単位の .npmrc の優先順位が関係します。
- ✅ まず通常のWeb閲覧、DNS、時刻設定が正常かを確認する
- ✅ Git、Docker、npmを別々にテストし、失敗する層を切り分ける
- ✅ プロキシを設定する前に、現在の設定値を保存しておく
- ❌ Docker CLIだけに設定してdaemon側の通信まで変わったと思い込まない
- ❌ アクセストークンやサブスクリプションリンクをログ、Issue、CIの出力へ貼り付けない
VPNクライアントはWindows、macOS、iOS、Android、Linuxで利用でき、公式クライアントのほか、Clash Verge、sing-box、Shadowrocketなどの互換クライアントにも導入できます。GitHubやRegistryの経路を切り替える場合は、まずクライアントで接続を確認し、その後に各ツールのプロキシを設定する順序が安全です。
用途に合う経路とプロトコルを選ぶ
開発通信では「一番速い回線」を固定するより、用途と時間帯に合う回線を選ぶ方が安定します。Gitのcloneは多数の小さなリクエストが発生し、Docker pullは大きなレイヤーを複数取得し、npm installは大量のメタデータと小さなアーカイブを処理します。そのため、同じ回線でも処理の印象が異なることがあります。
- GitHubのcloneやfetch:接続確立が安定し、短い接続を繰り返しても切れにくい回線を選びます。大規模リポジトリではGit LFSやsubmoduleの接続先も確認します。
- Dockerイメージのpull:長時間の転送が続くため、ピーク時に速度が変動しにくい経路を優先します。単一のレイヤーだけが失敗する場合は、VPN全体ではなくRegistry側の制限も疑います。
- npm install:DNS解決と多数のHTTPS接続が重要です。レジストリを変更する場合は、社内パッケージやlockfileとの整合性を必ず確認します。
回線タイプにも特徴があります。IEPL専用線は拠点間の専用経路を使うため、一般回線の混雑を受けにくい傾向があります。BGP中継は中継地点を経由して海外サービスへ接続する方式で、直接接続より安定する場合がありますが、区間ごとの混雑は残ります。直接接続は構成が単純である一方、利用しているネットワークの混雑や経路制御の影響を受けやすくなります。
プロトコルは、Shadowsocks、VMess、Trojan、Hysteria2、WireGuardなどが代表例です。WireGuardは軽量なVPN方式として扱いやすく、ShadowsocksやVMess、Trojanは互換クライアントで利用されることがあります。Hysteria2はQUIC/UDPを使うため、遅延やパケットロスがある環境で有利になる場合がありますが、UDPが制限されるネットワークでは逆に接続できないこともあります。プロトコル名だけで優劣を決めず、現在のネットワークとクライアントの組み合わせで確認してください。
ローカル環境で実際に設定する手順
ここでは、VPNクライアントでHTTPまたはSOCKSのローカルポートを提供できる前提で説明します。ポート番号はクライアントの画面に表示される値を使い、以下の例に出てくるアドレスやポートをそのまま固定しないでください。Clash Vergeやsing-boxなどでは、HTTPプロキシとSOCKSプロキシが別ポートになっていることがあります。
- 公式クライアントまたは互換クライアントにサブスクリプションリンクを導入し、回線を1つ選んで接続します。必要に応じて設定手順を確認し、まずIP確認ページで出口が切り替わっていることを確認します。
- ターミナルで現在のプロキシ環境変数を確認します。LinuxやmacOSでは
env | grep -i proxy、PowerShellではGet-ChildItem Env:*proxy*が使えます。 - Gitにだけ適用する場合は、
git config --global http.proxy http://127.0.0.1:PORTまたはgit config --global http.proxy socks5h://127.0.0.1:PORTを設定します。SOCKS5を使う場合は、DNSもプロキシ側で解決するsocks5hが適することがあります。 - 小さな公開リポジトリで
git ls-remoteを実行し、認証情報を入力する前に接続だけを確認します。cloneが途中で止まる場合は、同じ回線でfetchやRelease取得も試します。 - npmでは
npm config set proxy http://127.0.0.1:PORTとnpm config set https-proxy http://127.0.0.1:PORTを必要な範囲で設定し、npm config get registryで接続先を確認します。 - DockerはCLIとdaemonを分けて確認します。Docker DesktopではSettingsのResourcesまたはProxies周辺の設定を確認し、Linux Engineではsystemdのdrop-in設定でHTTP_PROXY、HTTPS_PROXY、NO_PROXYをdaemonへ渡した後、サービスを再読み込みします。
Gitで設定を解除するときは、git config --global --unset http.proxy のように、設定したキーを明示して削除します。npmも npm config delete proxy と npm config delete https-proxy で戻せます。Dockerではdaemonを再起動しないと変更が反映されないことがあるため、設定ファイルだけを編集して終わりにしないでください。
GitHub・Docker・npmで注意する設定
GitHubとGitの設定
GitHubではHTTPSとSSHで設定場所が異なります。HTTPSのcloneはGitのHTTPプロキシ設定を参照しやすい一方、SSHは通常のHTTPプロキシ設定を使いません。SSHを利用しているのにGitだけプロキシを設定して解決しない場合は、SSHの接続経路、ProxyJump、またはクライアントが提供するトンネル機能を個別に確認します。
リポジトリが大きい場合は、履歴全体が必要かを考え、必要に応じて浅いcloneやpartial cloneを使います。ただし、CIで後から全履歴、タグ、submodule、Git LFSのファイルが必要になるなら、単純な省略はビルド失敗につながります。速度改善と再現性のどちらを優先するかを先に決めてください。
Dockerのdaemonとレジストリ
docker pull が失敗するとき、まず docker info でクライアントとServerの情報を分けて確認します。Docker Desktopを使っている場合はGUIのdaemon設定を確認し、Linuxではsystemdサービスの環境変数とNO_PROXYを確認します。社内レジストリやローカルのミラーを使う場合、NO_PROXYにホスト名や内部ドメインを入れないと、不要な外部プロキシ経由になり、認証や名前解決が壊れることがあります。
また、Dockerfile内で依存パッケージを取得する処理と、daemonがイメージレイヤーを取得する処理は別です。前者はビルドコンテナ内のnpmやaptの設定、後者はDocker daemonの設定が必要です。片方だけ直しても、もう片方が同じ経路を使うとは限りません。
npm Registryと依存関係
npmでは、まず npm config get registry でレジストリを確認します。プロジェクト内の .npmrc、ユーザーの ~/.npmrc、環境変数、コマンドライン引数が異なる値を持つと、開発者の端末とCIで結果が変わります。特定のレジストリを利用する場合は、package-lock.jsonやnpm-shrinkwrap.jsonと方針を合わせ、公開パッケージと社内パッケージのスコープを明確にしてください。
タイムアウトだけを理由にリトライ回数やタイムアウト時間を大きくするのは最後の手段です。経路が不安定なままだと、CIの実行時間が長くなるだけでなく、断続的な失敗を見逃します。まずDNS、TLS、プロキシ認証、レジストリ応答の順にログを確認し、必要な設定だけを変更します。
CI/CDでの安全な高速化と運用
CI/CDでは、開発PCのVPN設定をそのままコピーすることはできません。ランナーがセルフホストか共有ホストか、Docker-in-Dockerを使うか、実行環境が毎回破棄されるかによって設定方法が異なります。共有ランナーでは、利用規約や組織のセキュリティポリシーを確認し、プロキシ認証情報をジョブのコマンドラインへ直接書かないでください。
推奨される方法は、プロキシURL、ユーザー名、パスワード、アクセストークンをCIのSecretまたはEnvironment Variablesに保存し、ジョブ開始時に必要なプロセスだけへ注入することです。ログで環境変数を表示しない、デバッグモードを常時有効にしない、エラー出力に認証URLが含まれないようにする、といった対策も必要です。サブスクリプションリンクも認証情報と同じように扱い、公開リポジトリの変数、Issue、ビルドアーティファクトへ保存してはいけません。
- ✅ Gitの取得、Dockerのpull、npm installを別々のステップとしてログ監視する
- ✅ npmキャッシュやDockerレイヤーキャッシュを使い、毎回同じデータを再取得しない
- ✅ NO_PROXYに内部レジストリ、社内Git、localhostなど必要な宛先を指定する
- ✅ CIで使う回線や出口を固定し、障害時に別の経路へ切り替える手順を文書化する
- ❌ Secretをechoしたり、プロキシ付きURLをエラーメッセージへ含めたりしない
- ❌ 開発者のローカルな ~/.npmrc やGit設定をそのままCIイメージへコピーしない
CIの最適化では、速度の数字だけでなく再現性も評価します。キャッシュが有効でも、依存関係のlockfileを無視したり、常に最新タグのDockerイメージを使ったりすると、ビルド結果が変わります。イメージは可能ならダイジェストで固定し、npmはlockfileを利用し、Gitの取得範囲をワークフローの目的に合わせて設定してください。
失敗したときの切り分けチェックリスト
設定後も接続できない場合は、VPNサービスそのものと開発ツールの設定を同時に変更しないことが重要です。まずVPNを切り替えずに通常の経路で再現し、次に別の回線で同じコマンドを実行します。特定の回線だけ失敗するなら経路の問題、すべての回線で失敗するなら認証、レジストリ、プロキシ設定、またはツール側の問題である可能性が高くなります。
- クライアントが接続済みで、ローカルプロキシポートが有効か確認する。
- DNS解決ができるか、対象ホスト名とリダイレクト先を確認する。
- HTTPSの証明書エラーやプロキシ認証エラーがないか確認する。
- Git、Docker daemon、npmのそれぞれが同じプロキシを参照しているか確認する。
- NO_PROXYの指定によって、意図せず直通になっていないか確認する。
- 回線を変更し、同じコマンドを再実行して結果を比較する。
- 問題が続く場合は、クライアント名、OS、使用プロトコル、失敗したコマンド、時刻、エラーメッセージを整理してサポートへ連絡する。
通信を高速化する目的で、TLS検証を無効にしたり、証明書チェックを恒久的に外したりするのは避けてください。短期的に接続できても、GitHubの認証情報、npmトークン、Dockerレジストリの資格情報を盗まれるリスクが増します。開発環境では速度よりも、経路の透明性、秘密情報の保護、元に戻せる設定を優先するべきです。