Slow Git fetches, Docker image timeouts, and unreliable npm installs are rarely caused by one setting alone. The result depends on the workstation client, the way a terminal program discovers proxy settings, the registry or package mirror being accessed, DNS resolution, and whether a CI runner is allowed to use the same route. A browser test can look normal while git, Docker, or a package manager continues to fail because each tool has its own network configuration.
This guide presents a practical way to evaluate a VPN for development work. The goal is not to force every connection through one tunnel. A better setup separates local services from external developer platforms, uses rules where possible, and applies explicit proxy settings to command-line tools that do not automatically follow the operating system. The same principles apply on Windows, macOS, Linux, and mobile devices, although the exact client controls differ.
Why developer traffic needs a different setup
Developer traffic is more varied than ordinary web browsing. A browser usually opens HTTPS connections and follows the system proxy or its own proxy preference. A development workstation may simultaneously run Git over HTTPS or SSH, Docker Engine, Docker Desktop, npm, pnpm, Yarn, language package managers, IDE extensions, Kubernetes tools, database clients, and local virtual machines. These programs do not necessarily share the same proxy behavior.
Git is a good example. A repository may be accessed through HTTPS, where Git can use an HTTP or HTTPS proxy, or through SSH, where the proxy must be handled with SSH-specific configuration or a compatible intermediary. Setting a proxy in the browser does not automatically configure Git. Likewise, setting a Git proxy does not change Docker’s daemon traffic or npm’s registry requests.
Docker introduces another separation. When a command such as docker pull is issued, the CLI may communicate with a local Docker daemon, while the daemon performs the actual image-layer downloads. With Docker Desktop, the daemon and its virtualized environment may have networking behavior separate from the host shell. On Linux, a system service may continue using its own environment even after a desktop VPN client changes the user session. This is why “the VPN is connected” is not enough evidence that image downloads use the intended route.
90+
Countries covered
200+
Available routes
5
Supported platforms
Unlimited
Online devices
For a developer-oriented VPN, route choice matters more than a single impressive speed claim. A nearby route may be preferable for ordinary source control, while a different route may work better for a registry or container endpoint. A client with rule-based routing can keep local development traffic direct while sending selected external domains through the tunnel. This reduces interference with LAN resources, internal Git servers, virtual machines, and services bound to localhost.
Choose the capture mode before tuning tools
Most desktop clients expose some combination of system proxy, rule-based routing, global mode, and TUN mode. These terms describe different layers of operation. System proxy changes settings that compatible applications can read. Rule-based routing decides where captured connections should go. Global mode generally sends captured traffic through one selected remote route instead of applying detailed domain rules. TUN mode creates a virtual network interface and captures a broader range of IP traffic.
System proxy for compatible applications
System proxy mode is often the least disruptive starting point. Browsers, many IDE components, and standard desktop applications can read the operating system’s HTTP or HTTPS proxy settings. It leaves local network access relatively easy to understand and allows applications that do not need the remote route to continue using the normal connection.
The limitation is application support. A command-line program may ignore system proxy settings, an IDE may use its own runtime, and a background service may run under a different user or service account. Some tools also support only HTTP CONNECT proxies and do not understand a SOCKS endpoint without an adapter. If a browser works but git clone or npm install fails, inspect the tool’s own configuration before changing the entire client mode.
TUN mode for broader capture
TUN mode is useful when several programs do not support a common proxy format. It routes IP traffic through a virtual adapter, allowing the client to apply rules to applications that bypass the system proxy. This can help with command-line tools, standalone updaters, UDP-dependent software, and development workflows split across multiple processes.
Broader capture also creates more points of failure. Docker Desktop, WSL, virtual machines, corporate endpoint security, local Kubernetes networks, and other virtual adapters may install their own routes. DNS behavior can change as well. If local containers cannot reach the host, an internal service disappears, or a virtual machine loses connectivity after TUN is enabled, check route priority and exclusions rather than assuming the remote route is slow.
| Mode | What it changes | Useful for | Typical caution |
|---|---|---|---|
| System proxy | Operating-system proxy settings | Browsers, compatible IDEs, standard desktop apps | Programs with their own network stack may bypass it |
| Rule-based routing | Destination selection for captured connections | Keeping local services direct while routing selected domains | Rules must match the actual hostname used by the tool |
| Global mode | A common route for captured traffic | Short troubleshooting sessions and broad connectivity tests | It can send local or internal traffic somewhere it should not go |
| TUN mode | Virtual-adapter IP traffic capture | CLI programs, UDP traffic, and applications ignoring proxies | May conflict with Docker, VMs, firewalls, or enterprise adapters |
Speed up GitHub access with explicit Git configuration
Git performance should be evaluated by the operation that is slow. A small fetch, a large clone, submodule checkout, release upload, and Git LFS transfer may use different endpoints and produce different results. Do not judge a route only by opening a repository page in a browser.
HTTPS and SSH are different paths
HTTPS repositories can usually use an HTTP or HTTPS proxy supported by Git. A typical configuration looks like this:
git config --global http.proxy http://127.0.0.1:PORT
git config --global https.proxy http://127.0.0.1:PORT
git config --global --get http.proxy
git config --global --get https.proxy
Replace PORT with the local port exposed by the client. Do not copy a port from a different application without checking whether it is an HTTP proxy or a SOCKS proxy. If the client exposes only SOCKS5, Git may require a compatible helper or a client feature that supports that proxy type. A protocol mismatch often looks like a timeout even when the remote route itself is available.
SSH uses a separate configuration path. Git does not automatically transform an SSH connection into an HTTP proxy request. If an organization uses SSH for repository access, configure the SSH client according to the available proxy method, or use HTTPS when that is acceptable for the project. Avoid placing access tokens or private keys in shell history, shared configuration files, or container images.
Avoid unnecessary Git retries
Repeatedly retrying a failed clone can make a poor route appear even worse. First check whether the problem is DNS resolution, TLS negotiation, authentication, or transfer interruption. Run a small read operation, then test the actual repository operation. For a large repository, shallow cloning can reduce the initial amount of history when the project workflow permits it, but it does not repair an incorrect proxy or unstable route.
Submodules deserve separate attention because their URLs may use a different host or protocol. A main repository may work over HTTPS while a submodule points to SSH. Inspect the submodule configuration and confirm that every required endpoint is covered by the intended rules. The same applies to Git LFS, release assets, and package files hosted outside the main code platform.
- ✅ Confirm whether the repository uses HTTPS or SSH before changing proxy settings.
- ✅ Check the proxy type and local port exposed by the desktop client.
- ✅ Test submodules and large-file transfers separately from the main repository.
- ❌ Do not assume that a browser connection proves Git uses the same route.
- ❌ Do not store credentials in a proxy URL or commit them to project configuration.
Configure Docker and container registry traffic
Docker troubleshooting begins by identifying which component makes the outbound request. The Docker CLI may talk to a local socket or a remote daemon. The daemon then resolves the registry name, negotiates TLS, authenticates, and downloads manifests and layers. A proxy configured only in the shell may therefore have no effect on the actual image transfer.
On Linux, Docker Engine commonly runs as a system service. Its proxy environment must be configured for that service and then reloaded according to the distribution’s service manager. On Docker Desktop, networking is handled through the Desktop application and its virtualized components, so use the application’s network or proxy settings where available. After changing the configuration, restart the relevant Docker component and verify with a harmless pull or an image operation appropriate to your environment.
Separate CLI proxy from daemon proxy
A Docker client proxy configuration can affect build-time traffic or client behavior, while the daemon’s proxy configuration controls daemon-originated requests. They are not interchangeable. BuildKit may also fetch base images, package indexes, and source archives during a build. If a Dockerfile works on one workstation but fails in CI, compare the daemon, builder, credentials, DNS, and proxy environment instead of copying only the local shell variables.
Be careful with proxy variables inside builds. Passing a proxy URL as a build argument can expose it in build history or image metadata, depending on how it is used. Prefer the secret and network features supported by the build system, and ensure that credentials are not written into layers. The VPN should provide a route; it should not become a reason to weaken image hygiene.
Registry rules and DNS
Container workflows may contact more than one hostname: the registry, authentication service, object storage endpoint, signature service, or a base image source. A rule that covers only the visible registry name may leave another required endpoint on a failing path. Review the error message and request flow, then add the smallest necessary set of destinations to the routing policy.
DNS is equally important. If the client routes the connection through a remote path but resolves the registry locally, the returned address may be unsuitable for that route. If all DNS requests are sent through TUN mode, local names used by development environments may stop resolving. Use a deliberate DNS policy with explicit local-domain exclusions where required, and test both public registry access and internal service access.
Make npm and package installs reliable
npm, pnpm, and Yarn can use registry settings, environment variables, system proxy behavior, or package-manager-specific configuration. A browser opening the registry website does not guarantee that package metadata and tarballs use the same endpoint. Lockfiles can also reference package hosts that differ from the configured default registry.
For npm, inspect the effective registry and proxy values before changing them:
npm config get registry
npm config get proxy
npm config get https-proxy
npm config get cafile
If a proxy is needed, configure it deliberately and keep the setting scoped to the correct user or project. A project-level configuration may be committed accidentally, while a user-level configuration may affect unrelated repositories. Credentials in registry URLs should be treated as secrets. Use the package manager’s supported authentication mechanism and a protected environment variable or credential store instead of writing tokens into a shared file.
Do not confuse a registry problem with a certificate problem. TLS interception by enterprise security software, an incorrect custom certificate authority, an expired internal certificate, or an outdated runtime can all produce connection errors. Disabling certificate verification is not a safe speed optimization. If a corporate network requires a trusted CA, install it through the approved operating-system or runtime process and verify the certificate chain.
Test installation in small stages
First request package metadata, then download a known dependency, and finally run the project’s normal clean install. This separates name resolution, registry access, archive transfer, and lifecycle scripts. A package may install successfully while a post-install script fails because that script contacts a different service. Record the exact hostname and error type before changing routes.
For repeatable builds, prefer a lockfile and a controlled cache strategy. A local cache can reduce repeated downloads, but it can also hide a broken route until the cache is cleared. Test both a warm-cache workflow and a clean-environment workflow. In CI, make sure the runner’s package manager, Node.js runtime, certificate store, and proxy variables match the intended build image.
Use a repeatable workstation test plan
A practical test should change one variable at a time. Select a route, record the client mode, and close competing VPN or proxy applications. Then test DNS, a normal HTTPS request, Git, Docker, and the package manager in that order. If the first network layer fails, later tool tests will not explain the root cause.
- Record the baseline. Note the current client mode, DNS mode, operating system proxy state, Docker mode, and whether the repository uses HTTPS or SSH.
- Check the local listener. Confirm that the proxy port exists and that its protocol matches the setting used by Git or npm.
- Test name resolution. Resolve the relevant hostnames from the same environment that will make the request. A host shell and a container may return different results.
- Test a small Git operation. Use a read-only fetch or metadata operation before attempting a large clone. Check submodules separately if the project needs them.
- Test Docker from the real daemon. Confirm whether Docker Desktop, a local service, or a remote daemon performs the pull.
- Test a clean package install. Use the project’s lockfile and inspect the effective registry and proxy configuration first.
- Repeat after changing only the route. Keep the client mode and tool settings constant so that route quality can be compared fairly.
When a test fails, classify the symptom. A DNS error points toward resolver policy or hostname rules. A connection timeout may indicate that the application bypassed the proxy, the proxy type is wrong, or the selected route cannot reach the destination. A TLS error requires certificate and time validation. An authentication failure is usually unrelated to route speed. This classification prevents random switching between global mode, TUN mode, and application settings.
- ✅ Keep local addresses, private registries, and development databases on explicit direct rules when appropriate.
- ✅ Use one client at a time to avoid competing virtual adapters and proxy listeners.
- ✅ Save the working configuration in secure, documented environment-specific notes.
- ❌ Do not send all internal traffic through a remote route merely because one external endpoint is slow.
- ❌ Do not treat a temporary successful download as proof that CI will use the same network path.
Account for CI runners and team workflows
A developer workstation and a CI runner are different network environments. The runner may be hosted in another region, run inside a container, use a restricted egress policy, or have no permission to create a TUN interface. A desktop VPN subscription cannot automatically change the network route of a hosted runner. Before depending on it for releases, confirm that the CI environment permits the required proxy variables, certificates, registry credentials, and outbound destinations.
For CI, an explicit HTTP or HTTPS proxy is often easier to audit than trying to install a full desktop client. Configure the runner or build container with protected variables, then pass only the settings required by Git, Docker, and the package manager. If Docker builds use a separate remote daemon, configure that daemon rather than assuming the runner’s environment controls it.
Keep secrets separate from route configuration. Proxy credentials, repository tokens, registry tokens, and signing keys should use the CI platform’s secret store. Avoid printing environment variables during diagnostics. When debugging, log sanitized hostnames, exit codes, and error categories instead of complete URLs containing credentials.
Teams should document which traffic is expected to be direct and which traffic requires a remote route. A short runbook can include the supported client platforms—Windows, macOS, iOS, Android, and Linux—the approved proxy type, the locations of registry settings, and the rollback procedure. If a VPN client provides subscription import for compatible clients such as Clash Verge, sing-box, or Shadowrocket, treat the imported configuration as a starting point and still verify application-specific behavior. Subscription import does not configure Docker daemons or CI services automatically.
Final checklist for a developer VPN
A useful developer VPN is not defined by a browser-only speed test. It should let you understand which traffic is captured, which route is selected, and which application is responsible for each connection. Before adopting a configuration, verify the following:
- ✅ The desktop client works on the operating system used for development.
- ✅ Git HTTPS, Git SSH, submodules, and large-file transfers have been considered separately.
- ✅ Docker Desktop or the Docker daemon has its own correct proxy and DNS settings.
- ✅ npm, pnpm, or Yarn uses the intended registry without exposing credentials.
- ✅ Local services, private networks, virtual machines, and containers remain reachable.
- ✅ CI has been tested independently rather than assumed to inherit workstation routing.
- ❌ No second VPN or proxy client is running at the same time during diagnosis.
- ❌ Certificate verification has not been disabled as a shortcut for connection failures.
The most stable approach is usually incremental. Begin with a normal client mode, identify the exact tool that fails, configure that tool explicitly, and add TUN mode only when broader capture is genuinely needed. Compare routes using the same Git operation, image source, package registry, and cache state. This produces a configuration that is easier to troubleshoot, safer for local development, and less likely to break when a project moves from a workstation to a container or CI runner.