# 为 git、npm、pip、Docker、apt 等开发工具配置代理

大多数命令行工具都读取同样的三个环境变量，其余工具也各有一个有文档说明的设置项。本页把两者都列出来，并附上那些会浪费你一下午的陷阱。


## 环境变量

```bash
export HTTP_PROXY="http://USER:PASS@res.hodlproxy.com:9000"
export HTTPS_PROXY="$HTTP_PROXY"
export NO_PROXY="localhost,127.0.0.1,.internal,.local"
# 有些工具只读取小写的变量名
export http_proxy="$HTTP_PROXY" https_proxy="$HTTPS_PROXY" no_proxy="$NO_PROXY"
```

- `HTTPS_PROXY` 是**用于** HTTPS 目标的代理；它的值仍然是 `http://` 开头的 URL，因为工具用普通 HTTP 与代理通信，再通过代理建立 TLS 隧道。
- `NO_PROXY` 列出不走代理的主机：内部镜像仓库、元数据服务、localhost。
- 密码中的特殊字符必须进行 URL 编码（`@` 写作 `%40`，`:` 写作 `%3A`），否则 URL 会被错误解析。


## git

```bash
git config --global http.proxy http://USER:PASS@res.hodlproxy.com:9000
# 仅对某个主机生效
git config --global http.https://github.com.proxy http://USER:PASS@res.hodlproxy.com:9000
# 使用 SOCKS5 并远程解析 DNS
git config --global http.proxy socks5h://USER:PASS@res.hodlproxy.com:9001
# 取消设置
git config --global --unset http.proxy
```

这些设置只对 HTTPS 远程仓库生效。SSH 远程仓库需要配置 `ProxyCommand`，例如在 `~/.ssh/config` 中使用 `ncat --proxy-type socks5 --proxy res.hodlproxy.com:9001 --proxy-auth USER:PASS %h %p`。


## npm 和 yarn

```bash
npm config set proxy http://USER:PASS@res.hodlproxy.com:9000
npm config set https-proxy http://USER:PASS@res.hodlproxy.com:9000

# yarn 1
yarn config set proxy http://USER:PASS@res.hodlproxy.com:9000
yarn config set https-proxy http://USER:PASS@res.hodlproxy.com:9000

# yarn 2 及以上
yarn config set httpProxy http://USER:PASS@res.hodlproxy.com:9000
yarn config set httpsProxy http://USER:PASS@res.hodlproxy.com:9000
```


## pip

```bash
pip install --proxy http://USER:PASS@res.hodlproxy.com:9000 requests

# 永久设置：pip.conf（Linux/macOS）或 pip.ini（Windows）
[global]
proxy = http://USER:PASS@res.hodlproxy.com:9000
```

只有安装了 PySocks 包，pip 才接受 SOCKS5 代理，否则会报缺少依赖的错误。在全新的机器上，请使用 HTTP 端口。


## Docker

Docker 有两个不同的代理设置，把它们搞混是最常见的陷阱。**守护进程**负责拉取镜像，不会读取你 shell 中的变量；**客户端**会把代理设置传递给构建过程和容器。

```ini
# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://USER:PASS@res.hodlproxy.com:9000"
Environment="HTTPS_PROXY=http://USER:PASS@res.hodlproxy.com:9000"
Environment="NO_PROXY=localhost,127.0.0.1"

# 然后
sudo systemctl daemon-reload && sudo systemctl restart docker
```

```json
{
  "proxies": {
    "default": {
      "httpProxy": "http://USER:PASS@res.hodlproxy.com:9000",
      "httpsProxy": "http://USER:PASS@res.hodlproxy.com:9000",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}
```

在 Docker Desktop 中，守护进程的代理设置位于 **Settings → Resources → Proxies**。


## apt

```text
Acquire::http::Proxy "http://USER:PASS@res.hodlproxy.com:9000/";
Acquire::https::Proxy "http://USER:PASS@res.hodlproxy.com:9000/";
```


## Go

Go 工具链会遵循 `HTTPS_PROXY` 和 `NO_PROXY`。`GOPROXY` 则完全是另一回事：它是模块镜像的地址，而不是网络代理，修改它并不会让流量经过出口。


## 该用哪种出口

- 软件包仓库和 git 托管平台不需要住宅级的可信度：[数据中心](https://hodlproxy.com/zh/datacenter-proxies)地址每月 $0.70 起，每个 IP 共享 100 GB，是最便宜且稳定的选择。
- 如果使用轮换住宅代理池，请保持粘性会话（`-sid-build1-ttl-30m`），避免大文件下载到一半时出口发生变化。
- 在服务器上优先使用 IP 白名单：这样环境变量和配置文件中就没有可能被其他用户和进程读取的凭据。


## 问题

**为什么 HTTPS_PROXY 的值是 http:// 开头？**

因为它描述的是工具如何与代理通信，而不是与目标通信。工具先用普通 HTTP 发送 CONNECT 请求，再通过隧道与目标协商 TLS。

**Docker 会使用我 shell 中的 HTTP_PROXY 吗？**

客户端在传递该变量的构建中会使用，但负责拉取镜像的守护进程不会：请在其 systemd drop-in 文件或 Docker Desktop 的代理设置中进行配置。

**NO_PROXY 有什么作用？**

它列出直接访问、不经过代理的主机：localhost、内部镜像仓库和云元数据地址。以点开头的条目会匹配整个域名。

**GOPROXY 是代理服务器吗？**

不是。GOPROXY 指定 Go 工具链使用的模块镜像。要让 Go 的网络流量经过代理，请设置 HTTPS_PROXY。

来源：https://hodlproxy.com/zh/guides/developer-tools-proxy-settings
