gera2ld.space

How To Develop Behind A Proxy - Complete Guide for Developers

Introduction

Recently I relocated to a region with significant network restrictions that impact development workflows. Accessing essential development resources requires routing traffic through a proxy. While a full VPN solution would be ideal, I found a SOCKS5 proxy to be more practical and flexible for development purposes while maintaining direct access to local services.

I’m using a SOCKS5 proxy running on localhost:1080 and it also exposes an HTTP proxy at localhost:1086.

This guide documents my journey configuring various development tools to work seamlessly behind a proxy, preserving both productivity and security.

Shell Configuration

The foundation of proxy configuration starts with shell environment variables:

# ~/.bashrc or ~/.zshrc
export HTTP_PROXY="http://localhost:1086"
export HTTPS_PROXY="http://localhost:1086"
export ALL_PROXY="socks5://localhost:1080"
export NO_PROXY="localhost,127.0.0.1,.local"

Command-line Tools

Fortunately, many development tools including npm, pip, yarn, and go automatically respect the HTTP_PROXY and HTTPS_PROXY environment variables, eliminating the need for separate proxy configurations.

SSH

SSH supports a ProxyCommand option to tunnel connections through a proxy server, but macOS’s built-in nc (netcat) command often fails with cryptic error messages when used for this purpose.

A more reliable alternative is ncat, part of the robust nmap toolkit, which handles proxy connections more gracefully. Install it with:

brew install nmap

This configuration also enables git operations behind a proxy when using SSH URLs (HTTP URLs are already supported via environment variables).

Apt (Debian/Ubuntu)

apt requires special proxy configuration compared to other package managers. This is particularly important for Docker images, which frequently use Debian/Ubuntu base images and rely on apt for package installation.

Create /etc/apt/apt.conf or /etc/apt/apt.conf.d/01_proxy.conf:

Acquire::http::Proxy "http://localhost:1080";
Acquire::https::Proxy "http://localhost:1080";

Docker Development

Colima on macOS

Colima runs Docker in a Linux VM, requiring careful proxy configuration at multiple levels:

Host macOS Configuration:

Edit ~/.colima/default/colima.yaml:

env:
  HTTP_PROXY: http://localhost:1080
  HTTPS_PROXY: http://localhost:1080
  NO_PROXY: localhost,127.0.0.1,.docker.internal

After updating your Colima configuration, run colima restart to apply the changes.

Note: Colima automatically inherits proxy environment variables from your macOS host system. If you already have proxy settings configured in your shell profile (.bashrc, .zshrc, etc.), this explicit Colima configuration may be redundant.

With Colima, no additional Docker daemon configuration is required. The docker pull command will automatically use the proxy settings configured in Colima.

Container-Specific Configuration

For individual containers, you can inject proxy settings using environment variables. Most container tools and orchestrators support these standard proxy variables:

HTTP_PROXY=http://localhost:1086
HTTPS_PROXY=http://localhost:1086
NO_PROXY=localhost,127.0.0.1,::1

Common methods to inject these variables:

  • Using -e flag with Docker/Podman: docker run -e HTTP_PROXY=http://localhost:1086 ...
  • In Dockerfile: ENV HTTP_PROXY=http://localhost:1086
  • In docker-compose: add to environment section

VS Code

VS Code is a popular Electron-based editor that requires specific proxy configuration when working behind network proxies.

Limitations

VS Code extensions don’t inherit container proxy settings - this remains a long-standing feature request dating back to 2017.

Development Containers (DevContainer)

For VS Code DevContainers, configure proxy settings in .devcontainer/devcontainer.json:

{
  "containerEnv": {
    "HTTP_PROXY": "http://192.168.5.2:1086",
    "HTTPS_PROXY": "http://192.168.5.2:1086",
    "NO_PROXY": "localhost,127.0.0.1,.local"
  }
}

Important Configuration Notes:

  • Host Proxy Mapping: My proxy runs on http://localhost:1086 on the host machine. The address 192.168.5.2 represents the host’s IP as seen from within the Colima VM (visible in Colima startup logs).
  • Environment Variable Limitation: Using ${localEnv:HTTP_PROXY} doesn’t work when the proxy is bound to localhost or 127.0.0.1 because these addresses resolve to the container’s loopback interface, not the host.
  • Alternative Approaches: While host.docker.internal might seem like a cleaner solution, it’s unreliable for proxy configurations due to DNS resolution issues in some environments.

Prefer Browser-Based Tools Over Desktop Apps

Many collaboration and development tools offer both desktop applications and browser-based versions. Tools like Slack, Teams, and even some IDEs now have web interfaces. I strongly recommend using the browser versions whenever possible, as they inherently respect your browser’s proxy configuration without requiring additional setup.

This approach eliminates the need to configure proxy settings individually for each application. Instead, you can manage all your proxy needs through browser extensions like SmartProxy, which provide convenient profile switching and enable/disable functionality right from your toolbar.

Conclusion

Network connectivity issues can be one of the most frustrating blockers in web development workflows. During my initial days working from this new region, I estimate nearly half of my development time was consumed by troubleshooting proxy-related challenges.

While developing behind a proxy requires configuration across multiple layers—from system-level settings to individual development tools—the investment pays dividends. Once properly configured, the proxy infrastructure becomes nearly transparent, allowing you to focus on actual development work rather than network gymnastics.

The key insight is understanding how each component in your toolchain handles proxy configuration. Whether through environment variables, configuration files, or dedicated settings, consistent proxy configuration ensures all your tools work harmoniously.

This comprehensive setup has enabled me to maintain full productivity even in restricted network environments, while preserving the flexibility to seamlessly disable proxy settings when working with local services.

Pro Tip: Create simple toggle scripts to quickly enable/disable proxy configurations based on your current network environment—this small automation can save significant time and frustration!