開発と AI · Clash 技術ブログ

Git、npm、Docker が Clash を経由しない場合は?ターミナルのプロキシ設定とタイムアウトの修正

Git、npm、Docker は、それぞれ異なるプロキシの参照元を使います。そのため、ターミナルの環境変数を変更しても docker pull が直るとは限りません。まずローカルポートを確認し、実際の設定元を一つずつ調べてください。

  • Git
  • npm
  • Docker
  • WSL2
目次

ブラウザは使えるのに Git、npm、Docker がタイムアウトする場合は、まずどのプロセスがリクエストを送っているか区別する

ブラウザから GitHub へアクセスできても、ブラウザがシステムプロキシを使っていることしか証明できません。Git は独自の設定と環境変数を読み、npm はさらに npmrc を読みます。Docker Desktop と Docker Engine には、それぞれ独立したバックグラウンドプロセスがあります。三つのコマンドが同時に失敗しても、異なる三つのプロキシ入口を使っている可能性があります。

問題を再現できるコマンドをそれぞれ一つ実行します。git ls-remote https://github.com/git/git.git HEAD、npm ping、docker pull hello-world を実行し、エラー文を記録してください。

Could not resolve host は名前解決の問題を示します。Connection refused はローカルポートでプロセスが待ち受けていない場合によく発生します。TLS または証明書のエラーは、タイムアウト時間を延ばしても解決しません。

各ツールのリクエストを実際に送るプロセス

ツール一般的なプロキシ設定元最初に確認する結果
Git HTTPSGit の設定または HTTP(S)_PROXYgit config と GIT_CURL_VERBOSE
npm環境変数、npmrc、registry の設定npm config get と npm ping
Docker DesktopDesktop の Proxies 設定Desktop のログと pull エラー
Linux Docker Enginedockerd の daemon.json または systemd 環境journalctl -u docker

まず 127.0.0.1 で実際にリクエストを待ち受けていることを確認する

Clash クライアントで mixed-port または HTTP ポートを確認し、慣例だけで 7890 と決めつけないでください。Windows では netstat -ano、macOS または Linux では lsof、ss でポートを確認できます。ポートが存在しなければ、どのツールを設定しても connection refused になります。

curl でプロキシを明示し、既知の HTTPS アドレスへアクセスする方法が、最小構成の入口テストです。成功したら、同じポートを Git または npm に設定します。curl も失敗する場合は、三つのツールの永続設定を変更し続けず、クライアント、ノード、ローカルファイアウォールを先に修正してください。

ローカル HTTP プロキシを一時的に検証する
# 将 7890 换成客户端显示的 HTTP 或 mixed 端口
curl -I -x http://127.0.0.1:7890 https://github.com

# Linux 查看监听
ss -lntp | grep 7890

# Windows 查看监听
netstat -ano | findstr :7890

起動ファイルへ書き込む前に、ターミナルで一度だけ一時テストする

HTTP_PROXY と HTTPS_PROXY は、現在のターミナルから起動し、これらを読み込むプログラムだけに適用されます。新しいターミナルで一時的に設定し、git または npm のテストを完了してからターミナルを閉じれば、設定は自然に失効します。結果が有効な場合に限り、PowerShell Profile、.zshrc、CI 環境へ書き込むかを決めてください。

NO_PROXY には localhost、127.0.0.1、直接接続が必要な社内ドメインを残します。すべての社内リクエストまで Clash へ送ると、ローカル開発サーバー、社内リポジトリ、Docker コンテナ間の通信で新たな問題が起きます。

一回のターミナルセッション用の環境変数
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1,.local

# PowerShell
$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"

Git では設定の出所を先に確認し、その後で追加か削除かを決める

git config --show-origin --get-regexp を使うと、プロキシ設定の取得元ファイルを確認できます。出力がない場合、多くは Git に個別のプロキシが保存されていないだけで、新しいエラーではありません。古いクライアントが残した http.proxy が閉じたポートを指していると、環境変数が正しくても Git が古い値を使い続ける可能性があります。

Git で固定 HTTPS プロキシが必要な場合は、ユーザーレベルの http.proxy だけを保存し、不要になったら --unset-all で削除します。SSH remote は Git の HTTP プロキシを通りません。[email protected] がタイムアウトする場合は、SSH、ProxyCommand を別途確認するか、比較のため一時的に HTTPS へ変更してください。

Git プロキシの表示、設定、削除
git config --show-origin --get-regexp '(^http\..*proxy$|^remote\..*\.proxy$)'

# 需要固定代理时再写入
git config --global http.proxy http://127.0.0.1:7890
git ls-remote https://github.com/git/git.git HEAD

# 以后改回环境变量或直连时删除
git config --global --unset-all http.proxy

npm のタイムアウトでは、プロキシと registry も切り分ける

npm の公式設定は HTTP_PROXY と HTTPS_PROXY を読み込み、ユーザーまたはプロジェクトの .npmrc に proxy、https-proxy、registry が保存されている場合もあります。registry が停止済みのミラーを指していると、プロキシノードを変更してもリクエスト先は変わりません。

npm config get proxy、npm config get https-proxy、npm config get registry を実行し、npm ping で現在の registry を検証します。プロジェクトディレクトリの .npmrc はユーザー設定を上書きできるため、同じコンピューターでもプロジェクトによって動作が異なる場合があります。

一時的な環境変数がすでに有効なら、npm の固定プロキシを追加する必要はありません。npm が環境変数を読み込んでいないことを確認してから、次の二項目を設定します。

npm プロキシの確認、設定、削除
npm config get proxy
npm config get https-proxy
npm config get registry
npm ping

# 仅在确实需要 npm 固定代理时设置
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm ping

# 改回环境变量或直连时清理
npm config delete proxy
npm config delete https-proxy

docker pull はバックグラウンドエンジンが実行するため、現在の shell を変更しても効かない場合がある

Docker Desktop には独自のプロキシ設定があります。Windows または macOS では Docker Desktop の Settings → Resources → Proxies を開き、System proxy を選択します。

システムプロキシが検出されない場合は Manual configuration を選び、Clash の HTTP または mixed ポートを入力します。

Docker の公式説明では、Desktop は daemon.json 内の daemon proxy 設定を読み込まないため、二つの場所を同時に何度も変更しないでください。

ネイティブ Linux では Docker Engine の dockerd がイメージを取得します。/etc/docker/daemon.json がすでに存在するかを確認し、次の proxies フィールドを既存の JSON へマージしてください。ファイル全体を上書きしてはいけません。保存後に JSON と daemon 設定を検証し、Docker を再起動します。

コンテナ内アプリへのプロキシ設定は別の項目です。daemon が実行する docker pull を修正するものではありません。

Linux Docker Engine の daemon プロキシ
# 把 proxies 合并进现有 /etc/docker/daemon.json,不要覆盖其他字段
{
  "proxies": {
    "http-proxy": "http://127.0.0.1:7890",
    "https-proxy": "http://127.0.0.1:7890",
    "no-proxy": "localhost,127.0.0.1,.local"
  }
}

sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
docker info | grep -i proxy
docker pull hello-world
Docker Desktop
Settings → Resources → Proxies で Docker Desktop proxy と Containers proxy を確認し、設定を適用してから hello-world を新規取得します。
Linux Docker Engine
サービスを再起動する前に dockerd --validate で daemon.json を検証し、失敗した場合は journalctl -u docker を確認します。
実行中のコンテナ
コンテナからインターネットへの接続が必要な場合だけプロキシ変数を渡し、ホストと社内ネットワークのアドレスを NO_PROXY に追加します。

WSL やコンテナ内では、127.0.0.1 が別の環境を指す

Windows 上の Clash は 127.0.0.1 でリッスンしますが、WSL2 またはコンテナ内の 127.0.0.1 はそれぞれの環境自身を指します。NAT ネットワークではホストへ到達できるアドレスを使用し、クライアントが LAN 接続を許可していること、Windows Firewall が必要な仮想サブネットだけを許可していることを確認してください。ミラーネットワークモードでは動作が異なるため、現在の WSL ネットワーク設定に合わせて検証します。

まず WSL またはコンテナ内から curl でホストのプロキシポートへアクセスします。ポート自体に到達できない間は、Git や npm を変更しても意味がありません。ポートへ到達できたら、環境変数を使うか、Clash TUN でこの種のプロセスを取り込むかを決めます。

ダウンロードできるようになったら、本当に必要な一層だけを残す

環境変数、Git のグローバル設定、npmrc、Docker の設定が同時に存在すると、後でポートを変更したりクライアントを終了したりした際、動作を説明しにくくなります。日常的に実際に使う一層だけを残し、テスト中に追加した固定プロキシを削除して、それに依存するコマンドを記録してください。

最後に新しいターミナルで git ls-remote https://github.com/git/git.git HEAD、npm ping、docker pull hello-world を順に実行します。三つとも成功し、対応するリクエストが Clash の接続ページにも表示されることを確認してください。

Clash を終了した後、ツールが閉じたローカルポートを参照し続けてはいけません。Connection refused がまだ表示される場合は、残っている固定プロキシ設定を削除します。

参考資料