Clash Developer Workflow: Proxy Git, SSH, And Homebrew
A broken GitHub clone or stalled package install can stop an entire development session. This guide shows developers how to connect Clash with Git, SSH, Homebrew, npm, pip, and Docker Hub, using TUN mode and targeted routing so command-line tools work consistently without manual proxy changes.
Why Developer Traffic Needs Its Own Clash Workflow
A browser can appear to work perfectly while a development terminal remains unable to clone a repository, download a package, or authenticate against a remote server. The reason is simple: system proxy mode usually changes HTTP and HTTPS settings for applications that choose to read them. Git, SSH, Homebrew, npm, pip, and Docker use different libraries, environment variables, and transport protocols. Some of them ignore the operating system proxy completely.
Clash becomes much more useful for development when the setup is designed around traffic paths instead of a single global switch. Web requests can use the normal system proxy, while command-line tools use explicit proxy variables or a local SOCKS5 listener. SSH can use a dedicated ProxyCommand, and applications that do not understand proxy settings can be captured by mihomo TUN mode. Targeted routing keeps private networks, local Git servers, package mirrors, and company services on DIRECT while sending selected developer services through a proxy group.
The examples in this guide assume a mihomo-based client such as Clash Verge Rev, Clash Verge, or another current Clash-compatible desktop client. The exact menu names vary, but the important values are normally the same: an HTTP mixed port such as 7890, a SOCKS5 port such as 7891, a controller port that should not be exposed publicly, and a rule mode that sends only the intended destinations to the proxy.
Use Localhost Ports, Not a Public Proxy Address
The ports below are examples of a local Clash installation. Confirm the actual HTTP and SOCKS ports in your client before copying commands. Never bind the external controller API or an unauthenticated proxy listener to a public interface; a reachable control port can expose configuration data and let another device change your proxy state.
Prepare Clash: Ports, Mode, and Developer Rules
Start by importing a valid subscription and selecting a working proxy group. Test the group in the client before debugging Git or package managers. If ordinary HTTPS pages cannot load through Clash, command-line tools will not become reliable merely by adding environment variables.
- Open the client settings and record the local HTTP or mixed port and the SOCKS5 port. A common arrangement is
7890for HTTP plus SOCKS5 and7891for SOCKS5 only. - Select Rule mode instead of Global mode. This lets domestic services, private address ranges, and explicitly listed mirrors remain direct.
- Enable System Proxy for applications that support HTTP proxy variables automatically, then use TUN mode when a tool or helper process ignores those settings.
- Choose a stable proxy group for code hosting, package registries, and container registries. Avoid a latency-testing group that changes nodes during a long build or upload.
- Run a basic check such as
curl -I https://example.comthrough the local port and inspect the Clash connection log.
For a shared configuration, add developer domains through a rule provider or a small local rule list rather than placing dozens of entries directly in the main file. A simplified mihomo configuration might look like this:
mixed-port: 7890
socks-port: 7891
mode: rule
allow-lan: false
log-level: info
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
rules:
- DOMAIN-SUFFIX,github.com,Developer
- DOMAIN-SUFFIX,githubusercontent.com,Developer
- DOMAIN-SUFFIX,githubassets.com,Developer
- DOMAIN-SUFFIX,npmjs.org,Developer
- DOMAIN-SUFFIX,pypi.org,Developer
- DOMAIN-SUFFIX,docker.io,Developer
- DOMAIN-SUFFIX,ghcr.io,Developer
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,DIRECT
The proxy group name Developer must exist under proxy-groups; otherwise the configuration will fail validation or the rule will not produce the expected outbound. The final MATCH line is deliberately shown as DIRECT for a split-tunnel design. If the actual requirement is to proxy all unmatched traffic, change it only after checking the effect on local networks, cloud credentials, and corporate systems.
TUN Mode Is Not a Substitute for Correct Rules
TUN captures more traffic, but it also captures traffic that should stay local. Keep RFC1918 ranges, loopback addresses, local DNS infrastructure, and internal domains on the direct path when appropriate. On Windows and macOS, TUN may require administrator approval; on Linux, route and DNS permissions must also be available.
Configure Git for HTTPS and SSH Repositories
Git has two completely different transport cases. An HTTPS remote such as https://github.com/example/project.git can use an HTTP or SOCKS-compatible proxy setting. An SSH remote such as [email protected]:example/project.git does not read Git's HTTP proxy option because the connection is made by the SSH client.
Git over HTTPS
For a temporary test, set the proxy for one command through the environment:
HTTPS_PROXY=http://127.0.0.1:7890 \
HTTP_PROXY=http://127.0.0.1:7890 \
git clone https://github.com/example/project.git
On PowerShell, use the corresponding syntax:
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:HTTP_PROXY = "http://127.0.0.1:7890"
git clone https://github.com/example/project.git
For a persistent Git-only setting, use git config --global:
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
git config --global --get http.proxy
git config --global --get https.proxy
Git's proxy URL must match the listener type. If the client exposes only SOCKS5, use a SOCKS URL where supported, for example socks5h://127.0.0.1:7891. The h matters: it asks the proxy to resolve the hostname instead of resolving it locally. When HTTPS cloning works in a browser but Git fails with a certificate or connection error, first inspect the configured proxy rather than disabling TLS verification.
Git over SSH
SSH normally connects directly to port 22, so a system HTTP proxy does not affect it. Add a host-specific rule to ~/.ssh/config and let the local SOCKS5 listener create the connection:
Host github.com
HostName github.com
User git
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p
Some versions of netcat use a different option format. If nc -x is unavailable, use a local helper that supports SOCKS5, or use mihomo TUN mode and remove the ProxyCommand line. Test the route before testing Git itself:
ssh -T -v [email protected]
git ls-remote [email protected]:example/project.git
Do not solve an SSH failure by changing the remote host to an unfamiliar address or by turning off host-key verification. Check the verbose output for the actual destination, proxy command, identity file, and host-key result. A successful authentication message can still be followed by a repository permission error, which is an account or repository issue rather than a Clash routing issue.
Keep HTTPS and SSH Tests Separate
git ls-remote https://... verifies Git's HTTP path, while git ls-remote [email protected]:... verifies SSH plus key authentication. Run both when a team uses mixed remotes, because success in one transport does not prove that the other is configured.
Proxy Homebrew, npm, and pip Without Breaking Local Mirrors
Package managers frequently spawn secondary processes, follow redirects, and contact more than one hostname. A command may reach the main registry through Clash but fail later when it downloads a tarball, metadata file, or binary from another domain. Watch the Clash log while installing and identify the complete request chain before adding rules.
Homebrew on macOS and Linux
Homebrew recognizes the standard proxy environment variables for many download operations. Use the variables for the current shell first:
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5h://127.0.0.1:7891
brew update
brew install jq
Homebrew may download from Git hosting, bottle mirrors, and API endpoints. If an organization provides an approved internal mirror, configure that mirror separately instead of forcing every Homebrew request through the external proxy. Check the effective configuration with brew config and inspect the error URL. A failure at github.com is a routing problem; a failure at an internal mirror may require DIRECT and a corporate DNS resolver.
npm and pip
npm can store proxy settings in its user configuration:
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm config get proxy
npm config get https-proxy
Remove these values when moving to a network with a different policy, or use shell-scoped variables for temporary work. Do not commit an npm configuration containing a proxy credential to a project repository.
pip supports environment variables and command-line options. A temporary installation can be tested with:
HTTPS_PROXY=http://127.0.0.1:7890 \
HTTP_PROXY=http://127.0.0.1:7890 \
python -m pip install requests
If a private Python index is used, keep it separate from public PyPI routing. Internal package hosts often need direct access, private certificates, or an authenticated corporate proxy. Do not add broad rules such as DOMAIN-KEYWORD,python,Developer; keyword rules can unexpectedly catch internal or unrelated domains. Prefer exact domains or suffixes that have been confirmed in the log.
| Tool | Typical proxy method | Useful verification | Common mistake |
|---|---|---|---|
| Git HTTPS | http.proxy or HTTPS_PROXY |
git ls-remote https://... |
Leaving an old proxy in global Git config |
| Git SSH | ProxyCommand or TUN |
ssh -T -v [email protected] |
Assuming HTTP proxy settings affect port 22 |
| Homebrew | Shell proxy variables | brew update |
Ignoring bottle or API redirect domains |
| npm | npm config or environment variables |
npm ping |
Saving credentials in a shared project file |
| pip | HTTP_PROXY, HTTPS_PROXY, or --proxy |
python -m pip install ... |
Proxying an internal index that requires direct access |
Make Docker Hub and Container Builds Consistent
Docker has two different proxy problems: the Docker daemon pulling images, and processes inside a build container downloading dependencies. Configuring a terminal's HTTPS_PROXY does not automatically configure the daemon, because the daemon may run as a separate service under another user.
For Docker Desktop, configure proxy behavior in the application's network or proxy settings, then restart Docker Desktop. For a native Linux Docker Engine, create a systemd drop-in for the daemon, using the local Clash address visible to the daemon. A typical example is:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl show --property=Environment docker
The address 127.0.0.1 is correct only when the daemon and Clash run in the same network namespace. With Docker Desktop, a VM-backed daemon may need the proxy configured in Docker Desktop instead. With a remote Docker host, the proxy must be reachable from that host; the local developer's loopback address will not work there.
Build-time downloads are separate. Pass proxy arguments only when the build requires them, and avoid baking credentials into image layers:
docker build \
--build-arg HTTP_PROXY=http://host.docker.internal:7890 \
--build-arg HTTPS_PROXY=http://host.docker.internal:7890 \
-t example/app:dev .
Use NO_PROXY for local registries, service discovery names, and private subnets. If image pulls fail, test docker pull and docker build independently. The first checks the daemon's registry route; the second may additionally require proxy settings inside the build environment.
Diagnose Failures by Layer
Changing several proxy settings at once makes a developer workstation difficult to reason about. Use one tool and one transport at a time, then confirm the request in Clash's connection log.
- Confirm the selected Clash group is alive and that the client is in Rule mode. Temporarily raise the log level to
debugonly while testing. - Test DNS and HTTPS separately with
nslookup,curl -v, or the tool's own diagnostic command. A DNS answer proves resolution, not successful proxy forwarding. - Check whether the destination matched the expected rule. A rule placed after
MATCHis never reached, and a domain rule may not match a raw IP address. - Inspect environment variables with
env | grep -i proxyon macOS/Linux orGet-ChildItem Env:*proxy*in PowerShell. Remove stale values before retesting. - For SSH, use
ssh -vand verify that the configuredProxyCommandis actually executed. For Docker, inspect the daemon environment separately. - After the test, restore normal log level and remove temporary credentials or proxy values from shell history and configuration files.
| Symptom | Likely layer | First action |
|---|---|---|
| Browser works, Git HTTPS times out | Git proxy configuration | Check git config --global --get-regexp proxy |
| Git HTTPS works, Git SSH fails | SSH transport or port 22 | Run ssh -T -v and inspect ProxyCommand |
| npm reaches the registry but tarball download fails | Redirect or secondary domain | Read the failing hostname in the Clash log |
| Docker pull fails while curl works | Docker daemon environment | Inspect daemon proxy settings and restart it |
| Internal services stop working in TUN mode | Overbroad routing or DNS | Add verified private domains and CIDRs to DIRECT |
Safe Defaults for Daily Development
A practical daily configuration is usually a combination of Rule mode, a stable developer proxy group, explicit proxy variables for short-lived terminal sessions, and TUN mode only when required. Keep internal Git, artifact repositories, databases, SSH bastions, and service discovery domains outside the external proxy path unless company policy says otherwise.
- Use
DIRECTfor loopback, private CIDRs, and confirmed internal suffixes. - Use
DOMAIN-SUFFIXfor known services instead of broad keyword matching. - Place specific developer rules before general region or catch-all rules.
- Use
socks5h://when a command-line tool supports it and remote DNS resolution is required. - Prefer environment variables for temporary work and audit persistent settings regularly.
- Keep SSH host rules specific to the required hosts rather than proxying every SSH connection.
- Do not expose
mixed-portor the external controller to an untrusted LAN without authentication and a deliberate firewall policy.
For a first setup, Get Clash and then follow the Open the tutorial workflow to import a subscription, select a group, and verify the basic system proxy before applying developer-specific settings.
Developer Proxy FAQ
Should Git use the HTTP port or the SOCKS5 port?
Git HTTPS commonly works with the local HTTP or mixed port, such as http://127.0.0.1:7890. Use the SOCKS5 port when the client and its proxy syntax support it, preferably with remote DNS through socks5h. Git SSH needs an SSH-aware proxy command or TUN mode; setting https.proxy alone does not proxy SSH.
Why does TUN mode fix one tool but break an internal service?
TUN captures traffic below the application layer, including programs that ignore HTTP proxy variables. It can therefore capture internal traffic as well. Add verified internal domains and private address ranges to direct rules, check DNS behavior, and avoid using a broad catch-all proxy rule until local access has been confirmed.
Why does Docker ignore the proxy configured in my terminal?
The Docker daemon is a separate process and often runs as a system service or inside a VM. Configure the daemon or Docker Desktop directly, then restart it. Build commands may also need build arguments, because daemon-level proxy settings and in-container download settings are separate layers.
How can old proxy settings be removed?
Check Git with git config --global --get-regexp proxy, npm with npm config list, and the current shell's proxy environment variables. Remove only the entries that are no longer valid, then open a new terminal and repeat a single-tool test while watching the Clash log.
Set Up a Reliable Developer Route
Use the download center to choose a current Clash client, enable the appropriate local ports, and apply the smallest rule set that covers your actual repositories and registries. Once each transport has been tested independently, Git, SSH, Homebrew, npm, pip, and Docker can share the same stable routing strategy without repeatedly changing manual proxy settings.