GitHubのcloneが途中で止まる、Docker Hubからimageをpullできない、npm installが何度もタイムアウトする。開発者の通信トラブルは、単純に「回線速度が遅い」だけでは説明できません。アクセス先までの経路、DNSの応答、認証サーバーとの接続、コンテナ内部のプロキシ設定、パッケージレジストリの選択など、開発環境の複数の層が関係しています。

VPNを導入すると経路を変更できますが、すべての問題が自動的に解決するわけではありません。GitのSSH接続だけが対象外になっていたり、Dockerデーモンがホストの設定を引き継いでいなかったり、npmだけが別のプロキシ設定を使っていたりすることがあります。本稿では、ローカルPC、開発ツール、コンテナ、CI/CDを分けて確認し、必要な通信だけを適切な経路へ送る考え方を整理します。

90+

接続可能な国

200+

利用可能な回線

5

対応プラットフォーム

不限

同時接続台数

開発通信を四つの層で整理する

開発環境の通信は、まずOS全体の経路、次にアプリケーションのプロキシ設定、その次にコンテナや仮想環境のネットワーク、最後にCI/CD実行環境という順番で考えると整理しやすくなります。OSのVPNクライアントが接続済みでも、アプリケーションが独自のDNSやプロキシを使っていれば、期待したルートにならないことがあります。

Windows、macOS、Android、iOS、Linuxの公式クライアントを使う場合は、まずクライアントへログインし、利用可能なサブスクリプションを取得して接続状態を確認します。Clash Verge、sing-box、Shadowrocketなどの互換クライアントを使う場合は、サブスクリプションリンクを追加した後、対象のプロファイルを選択し、システムプロキシ、TUN、DNSの扱いを個別に確認します。設定をインポートしただけでは、OS全体の通信がその経路を通るとは限りません。

プロトコルにも役割の違いがあります。WireGuardはVPNトンネルを構成する方式で、OSやクライアントが仮想インターフェースを提供する構成に向いています。Shadowsocks、VMess、Trojan、Hysteria2はプロキシクライアントや関連エコシステムで使われる方式であり、ブラウザーだけを対象にするのか、TUNでより広い通信を取り込むのかはクライアント側の機能に依存します。プロトコル名だけで、GitやDockerが必ず対応すると判断してはいけません。

確認する項目 典型的な問題 対処の方向
OS VPN接続、DNS、ルーティング、キルスイッチ 名前解決はできるが経路が不安定 別の地域・回線へ切り替え、DNSとルートを再確認する
アプリ Git、npm、パッケージマネージャーの設定 ブラウザーだけ動き、CLIが失敗する HTTP_PROXY、HTTPS_PROXY、Gitの設定を確認する
コンテナ Dockerデーモン、build、run時の環境変数 ホストは接続できるがpullやbuildに失敗する デーモンとコンテナへ必要な設定を別々に渡す
CI/CD runnerの地域、シークレット、証明書、キャッシュ ローカルでは成功するがジョブだけ失敗する 実行環境内でDNS、経路、レジストリ接続を検証する
重要な考え方

VPNは「開発ツール」そのものではなく、開発ツールが利用するネットワーク経路を調整する基盤です。接続後も、各ツールがどの設定を読み取っているかを確認する必要があります。

GitHubのcloneと依存リポジトリを安定させる

GitHubの通信では、リポジトリ本体のclone、サブモジュールの取得、Git LFSのオブジェクト取得、release assetのダウンロードが別々のホストや接続方式を使うことがあります。cloneだけ成功しても、サブモジュールやLFSで止まるなら、GitHubの一部機能だけでなく、追加ホストへの名前解決とルーティングを確認しましょう。

HTTPSを使う場合は、Gitがシステムプロキシを自動的に利用するとは限りません。Gitのグローバル設定に残っている古いプロキシ、シェルで設定した環境変数、VPNクライアントのシステムプロキシが競合すると、接続が不安定になります。SSHを使う場合は、ブラウザー用プロキシの対象外になりやすいため、SSHがVPNまたはTUNの経路へ入っているかを個別に確認します。

切り分けでは、まず小さな公開リポジトリへの接続、次に対象リポジトリのclone、最後にサブモジュールやLFSという順番で試すと、問題の位置を把握しやすくなります。認証エラーとタイムアウトも分けて考えてください。認証エラーはトークン、SSH鍵、権限の問題であることが多く、VPNの回線変更だけでは解消しません。

Gitの経路を選ぶときの確認点

  • ✅ HTTPSとSSHのどちらを使っているかを確認し、方式ごとに経路を検証する。
  • ✅ サブモジュール、Git LFS、release assetなど追加通信の有無を確認する。
  • ✅ Gitのプロキシ設定とHTTP_PROXY、HTTPS_PROXYの重複を確認する。
  • ✅ 別の地域や回線へ切り替えた後、同じ操作を同じ条件で比較する。
  • ❌ 認証失敗を、すべてVPNやDNSの問題だと決めつけない。
  • ❌ clone中に複数のVPNクライアントを同時に起動してルートを競合させない。

企業ネットワークや管理された開発環境では、TLS検査用の証明書が端末に追加されていることもあります。VPNを経由した後だけ証明書エラーが出る場合は、検証を無効化するのではなく、信頼ストア、GitのCA設定、社内プロキシの要件を確認してください。証明書検証を無効にすると、通信先の真正性を確認できなくなります。

Docker Hubのpullとbuildを分離して調整する

Dockerでは、ホスト上のブラウザーが通信できることと、Docker imageをpullできることは同じ意味ではありません。imageのpullはDocker CLIからDockerデーモンへ依頼され、実際のレジストリ通信はデーモン側で行われます。Docker Desktopを使う場合も、CLI、Desktopの内部VM、デーモン、build環境が別のネットワーク境界を持つことがあります。

まず、公開imageのpullだけが失敗するのか、Dockerfileのbuild中にベースimageの取得で失敗するのかを分けます。前者はレジストリや認証、デーモンのプロキシを疑い、後者はbuildkit、build時のDNS、RUN命令内のパッケージ取得まで確認します。ホストのシェルで設定したHTTP_PROXYを、そのままDockerデーモンが利用するとは限りません。

コンテナ内でnpmやaptなどを実行する場合は、さらに別の設定が必要です。build時だけ必要なプロキシと、実行時のアプリケーション通信を同じ設定にすると、認証情報がイメージレイヤーや環境変数に残る危険があります。秘密情報はDockerfileへ直接書かず、利用するビルド基盤が提供するsecret機能や安全な変数管理を使い、生成されたイメージに不要な値を残さない設計にします。

Dockerで確認する順番

  1. ホストからレジストリの名前解決とHTTPS接続を確認する。
  2. Dockerデーモンが参照するプロキシ、DNS、証明書設定を確認する。
  3. 公開imageのpullと、認証が必要なimageのpullを分けて試す。
  4. DockerfileのFROMで失敗するのか、RUN命令で失敗するのかを確認する。
  5. build時と実行時のプロキシを分け、認証情報がイメージへ残っていないか調べる。

npm installの停止とレジストリ設定を見直す

npm installが終わらない場合、npmレジストリ本体だけでなく、依存関係のtarball、Git依存、postinstallで呼び出される外部サービスへの通信が関係していることがあります。package-lock.jsonの取得は成功しても、実際のパッケージ本体のダウンロードで止まることがあるため、ログに表示される最後のURLや処理段階を確認しましょう。

npmの設定では、registry、proxy、https-proxy、strict-ssl、認証トークンを確認します。VPNを接続する前から設定していたプロキシが残っていると、VPN経由の通信と二重になり、タイムアウトやTLSエラーを起こすことがあります。不要な設定を一度整理し、会社やチームが指定するレジストリを使う場合は、勝手に別の公開レジストリへ切り替えず、認証と証明書の要件を確認してください。

npm installを再試行する前に、DNSがレジストリを正しく解決できるか、HTTPS証明書が検証できるか、対象URLへ接続できるかを分けて調べます。パッケージマネージャーのTLS検証を無効にする方法は、短期的にエラーを隠せても安全な解決ではありません。特に認証トークンを含む設定ファイルをログへ出力したり、Dockerイメージへコピーしたりしないよう注意してください。

実務での結論

npmの問題は「速度」よりも、レジストリ、依存先、プロキシ、証明書、認証のどこで止まったかをログから特定するほうが早く解決できます。

手を動かして原因を切り分ける手順

ここでは、設定を一度に変更せず、接続範囲を段階的に広げる手順を紹介します。最初からグローバルモードに固定するのではなく、開発作業に必要な通信だけを確認し、国内サービスや社内LANまで意図せず経由させないようにします。

  1. クライアントを一つに絞る。公式クライアント、Clash Verge、sing-box、Shadowrocketなどを同時に起動せず、現在の接続方式と選択中のプロファイルを記録します。
  2. VPN接続後にDNSを確認する。GitHub、Docker Hub、npmで利用するホスト名が解決できるかを調べ、名前解決だけ成功してHTTPS接続が失敗する場合は、経路や証明書を別に確認します。
  3. Gitを単独で試す。HTTPSまたはSSHのどちらか一方でcloneを実行し、認証、名前解決、転送のどの段階で止まるかをログから確認します。
  4. Dockerを単独で試す。ホストの通信ではなく、Dockerデーモンがレジストリへ到達できるかを確認します。buildまで進めた場合は、FROMとRUNのどちらで失敗したかを分けます。
  5. npmを単独で試す。registryとプロキシの設定を確認し、依存パッケージの取得先が想定どおりかを調べます。
  6. 最後にルールを細かくする。すべての通信を同じ出口へ送るのではなく、開発ツールに必要な宛先だけをルールへ追加し、社内サービスやローカル開発用アドレスは直接接続に戻します。

一つの変更ごとに元の設定へ戻せるよう、プロファイルを複製して比較すると安全です。地域を変更したときは、同じリポジトリ、同じレジストリ、同じネットワーク環境で再確認します。測定結果を断定的な速度や成功率に置き換えるのではなく、失敗箇所、エラー内容、再現条件を記録することが重要です。

CI/CDではrunnerと秘密情報を分けて考える

ローカルPCで成功する設定を、そのままCI/CDへコピーしてはいけません。CI runnerは別の地域、別のOS、別のDNS、別の証明書ストアで動作するため、VPNの接続方式やプロキシの環境変数も異なります。runnerが一時的な実行環境なら、ジョブ開始時にクライアントや設定を読み込む工程が必要になることもあります。

CI/CDでVPNを利用する場合は、まず対象が依存パッケージの取得だけなのか、デプロイ先への接続も含むのかを明確にします。すべてのジョブをトンネルへ送ると、不要な通信まで経路が変わり、ログ収集や内部サービスとの接続に影響する場合があります。可能であれば、依存関係のキャッシュ、社内レジストリ、許可された出口回線など、組織の運用方針に沿って構成します。

サブスクリプションリンク、秘密鍵、アクセストークン、プロキシ認証情報は、リポジトリへ直接保存しないでください。CIのsecret管理を使い、ログに値が表示されないマスキング、ジョブ終了後の削除、権限の最小化を行います。VPN接続が成功しても、秘密情報の保護が不十分なら開発環境全体の安全性は高まりません。

  • ✅ ローカルとCIでOS、DNS、runnerの地域、プロキシ設定が異なることを前提にする。
  • ✅ 接続が必要なジョブと、直接接続でよいジョブを分ける。
  • ✅ サブスクリプション、秘密鍵、トークンをCIのsecret管理へ置く。
  • ✅ 失敗時のログから、DNS、TLS、認証、レジストリ、経路を区別する。
  • ❌ CIのログへ環境変数や設定ファイルをそのまま出力しない。
最終チェック

開発者向けVPNの設定は、速い回線を選ぶだけで終わりません。OS、CLI、コンテナ、CI/CDの各層で、必要な通信が正しい経路を通り、認証情報と証明書が安全に扱われているかを順番に確認することが、安定した開発環境への近道です。