На хосте Clash работает прекрасно, а внутри контейнера всё уходит в таймаут. Причина простая: у контейнера собственное сетевое пространство имён, так что 127.0.0.1 означает сам контейнер.
Основное условие: включить allow-lan
Какой бы подход вы ни выбрали, первый шаг одинаков — сменить адрес прослушивания Clash с 127.0.0.1 на 0.0.0.0:
Включите Allow LAN в Clash Verge или пропишите в конфигурации:
allow-lan: true
bind-address: "*"
mixed-port: 7897Проверка:
netstat -an | findstr 78970.0.0.0:7897 — получилось. 127.0.0.1:7897 — нет.
Docker: три отдельных сценария
Основная путаница возникает от непонимания, что эти три вещи настраиваются по отдельности.
Сценарий 1: docker pull не тянет образы
Здесь в сеть выходит демон Docker; контейнеры ни при чём.
Docker Desktop (Windows / macOS): Settings → Resources → Proxies → включите Manual proxy configuration и заполните:
HTTP: http://127.0.0.1:7897
HTTPS: http://127.0.0.1:7897
Bypass: localhost,127.0.0.1,*.localДемон Docker Desktop работает в виртуальной машине, но достаёт до loopback хоста, так что 127.0.0.1 здесь верно.
Docker на Linux (systemd):
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/proxy.conf > /dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7897"
Environment="HTTPS_PROXY=http://127.0.0.1:7897"
Environment="NO_PROXY=localhost,127.0.0.1,::1,*.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF
sudo systemctl daemon-reload
sudo systemctl restart dockerПроверка:
sudo systemctl show --property=Environment dockerСценарий 2: установка зависимостей уходит в таймаут при docker build
Сборка идёт внутри временного контейнера, так что настройки надо передать явно:
docker build \
--build-arg HTTP_PROXY=http://host.docker.internal:7897 \
--build-arg HTTPS_PROXY=http://host.docker.internal:7897 \
--build-arg NO_PROXY=localhost,127.0.0.1 \
-t myimage .Объявлять эти ARG в Dockerfile не нужно — у Docker есть встроенная поддержка именно этих имён.
Сценарий 3: работающему контейнеру нужна сеть
docker run -it \
-e HTTP_PROXY=http://host.docker.internal:7897 \
-e HTTPS_PROXY=http://host.docker.internal:7897 \
-e NO_PROXY=localhost,127.0.0.1,::1 \
--add-host=host.docker.internal:host-gateway \
ubuntu bashВ docker-compose:
services:
app:
image: myimage
environment:
- HTTP_PROXY=http://host.docker.internal:7897
- HTTPS_PROXY=http://host.docker.internal:7897
- NO_PROXY=localhost,127.0.0.1,::1,app,db
extra_hosts:
- "host.docker.internal:host-gateway"Использование LAN-адреса хоста вместо host.docker.internal
Если host.docker.internal недоступен, берите локальный адрес хоста напрямую:
# на Windows
ipconfig
# на Linux — адрес моста docker0 (хост с точки зрения контейнера)
ip addr show docker0 # обычно 172.17.0.1Затем подставьте этот адрес вместо host.docker.internal.
Путь попроще: включить TUN
Настроек выше набирается немало. Если возиться не хочется, включите режим TUN — весь трафик перехватывается на сетевом уровне, и ни демон Docker, ни контейнеры настраивать не надо.
Под TUN не забудьте добавить подсети Docker в прямые правила, чтобы трафик между контейнерами не проксировался:
prepend-rules:
- IP-CIDR,172.17.0.0/16,DIRECT,no-resolve
- IP-CIDR,172.18.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolveWSL2: два режима сети
С некоторой версии WSL2 поддерживает зеркальную сеть, и два режима настраиваются совершенно по-разному. Сначала выясните, какой у вас.
# выполните внутри WSL2
cat /etc/resolv.conf
ip route show defaultРежим 1: NAT (по умолчанию, традиционный)
У WSL2 свой виртуальный адаптер, и хост выглядит для него адресом шлюза.
# получить IP хоста и задать прокси
export HOST_IP=$(ip route show default | awk '{print $3}')
export HTTP_PROXY="http://$HOST_IP:7897"
export HTTPS_PROXY="http://$HOST_IP:7897"
export ALL_PROXY="socks5://$HOST_IP:7897"
export NO_PROXY="localhost,127.0.0.1,::1,*.local"Положите это в ~/.bashrc или ~/.zshrc как пару переключателей:
proxyon() {
local host_ip=$(ip route show default | awk '{print $3}')
export HTTP_PROXY="http://${host_ip}:7897"
export HTTPS_PROXY="http://${host_ip}:7897"
export ALL_PROXY="socks5://${host_ip}:7897"
export NO_PROXY="localhost,127.0.0.1,::1,*.local"
echo "proxy on → ${host_ip}:7897"
}
proxyoff() {
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
echo "proxy off"
}Почему адрес надо получать динамически: адрес виртуального адаптера WSL2 может меняться при каждой перезагрузке хоста, так что жёстко прописанное значение перестаёт работать.
Режим 2: зеркальная сеть (более новые Windows)
Включается в %USERPROFILE%\.wslconfig:
[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=trueПосле правки выполните wsl --shutdown, чтобы перезапустить WSL.
В зеркальном режиме WSL2 делит сетевое пространство имён с хостом, так что 127.0.0.1 работает напрямую:
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"autoProxy=true вдобавок заставляет WSL наследовать системный прокси Windows, так что во многих случаях переменные окружения вообще не нужны.
Проверка, что прокси работает
# посмотреть переменные окружения
env | grep -i proxy
# попробовать
curl -I https://www.google.com
# посмотреть выходной IP (должен быть узла)
curl https://api.ipify.orgЕсли curl работает, а apt и pip по-прежнему нет, у этих инструментов своя настройка прокси; см. шпаргалку по прокси для разработчиков.
Диагностический чек-лист
Одна быстрая проверка, выполняется внутри контейнера или WSL:
curl -v --connect-timeout 5 http://ip-хоста:7897Соединение вообще произошло — даже с ответом 400 — значит, сетевой уровень в порядке; Connection refused указывает на allow-lan или брандмауэр.
Коротко
- Первый шаг всегда: allow-lan плюс исключение в брандмауэре
- Три сценария Docker настраиваются каждый отдельно: daemon, build, run
host.docker.internalна Linux требует--add-host- Для WSL2 сначала определите режим сети: NAT требует динамически получать IP шлюза, зеркальный берёт 127.0.0.1
- Не забывайте про приватные диапазоны и имена сервисов в NO_PROXY
- Если всё это слишком, включите TUN — но добавьте подсети Docker в прямые правила
Смотрите также: шпаргалка по прокси для разработчиков и внутреннее устройство TUN.
Смежные документы
Справочная таблица, которую стоит сохранить. Команда для каждого инструмента, где лежит его файл настроек, как всё отменить и почему часть инструментов игнорирует переменные окружения.
Нулевая настройка для каждого устройства в доме. Компромиссы трёх подходов (боковой роутер, TProxy, TUN), полная конфигурация и служба systemd, правила брандмауэра и отказоустойчивость, чтобы домашние оставались в сети.
Полный RESTful API, который открывает external-controller: переключение узлов, просмотр соединений, перезагрузка конфигурации, развёртывание веб-панели и несколько практичных скриптов.