Настройка прокси и SOCKS5 в Docker: демон, сборка, контейнеры и мосты
В Docker нет одного переключателя прокси. Демон, процесс сборки и каждый контейнер читают настройки прокси в разных местах — а SOCKS5 вообще не поддерживается демоном. Вот как настроить каждый уровень и проверить, что он работает.
Настройка прокси и SOCKS5 в Docker: демон, сборка, контейнеры и мосты
Если вы ищете «socks5 configurator», потому что docker pull постоянно истекает по тайм-ауту, вы не одиноки. В Docker есть как минимум три уровня прокси, и они не используют общие настройки. Прокси, который работает для docker pull, может не помочь apt-get внутри сборки, а SOCKS5 — распространённый во многих прокси-сервисах — не принимается прокси-переменными демона Docker. Это руководство проходит по каждому уровню с готовыми к копированию конфигурациями и шагами проверки, чтобы вы могли направлять через прокси только то, что нужно, и избегать утечек DNS или учётных данных.
Три уровня прокси в Docker (и где применяется каждый из них)
| Уровень | На что влияет | Где задаётся | Поддержка протоколов |
|---|---|---|---|
| Демон | docker pull, docker push, аутентификация в реестре |
drop-in systemd (Linux) или настройки Docker Desktop | URL прокси HTTP/HTTPS |
| Сборка | Команды RUN во время docker build (apt, pip, npm) |
--build-arg + ARG в Dockerfile |
URL прокси HTTP/HTTPS |
| Среда выполнения контейнера | Трафик из вашего приложения внутри контейнера | флаги -e или environment в Compose |
Зависит от приложения (HTTP, HTTPS, SOCKS5, если приложение поддерживает) |
Четвёртое место, о котором забывают: собственный менеджер пакетов и инструменты хоста. Если вы не можете достучаться до реестра Docker, то обычно не можете достучаться и до apt или pip на хосте. Сначала настройте прокси на уровне хоста, затем настраивайте Docker. Для маршрутизации по приложениям на хосте см. наше руководство по настройке SOCKS5 для браузеров, SSH, curl, git и Python.
Прокси на уровне демона: для загрузки образов и обращения к реестрам
Демон Docker читает стандартные переменные окружения прокси из своей службы systemd. Создайте drop-in-файл:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<'EOF'
[Service]
Environment=HTTP_PROXY=http://user:[email protected]:3128
Environment=HTTPS_PROXY=http://user:[email protected]:3128
Environment=NO_PROXY=localhost,127.0.0.1,::1,.internal.example,registry.internal.example
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Примечания:
- Значение — это URL прокси. Для стандартного HTTP-прокси, поддерживающего CONNECT, используйте
http://. Если сама конечная точка прокси обёрнута в TLS, используйтеhttps://. NO_PROXYдолжен включать любой внутренний реестр или хост, которые вы не хотите проксировать. Ведущая точка в.internal.exampleво многих реализациях соответствует поддоменам, но поведение может различаться.- Учётные данные в файле systemd видны пользователю root. Для общих машин рассмотрите локальный форвардер, который не требует учётных данных в окружении.
Проверка:
docker info | grep -i -A2 'Proxy'
Вы должны увидеть строки HTTP Proxy, HTTPS Proxy и No Proxy. Если они пусты, демон не подхватил drop-in.
Затем проверьте загрузку:
docker pull alpine:latest
Если всё ещё не работает, проверьте логи демона:
journalctl -u docker.service --no-pager -n 50
В Docker Desktop (macOS/Windows) есть настройка прокси в графическом интерфейсе: Settings, Resources, Proxies. Она записывает те же переменные для демона.
Прокси на этапе сборки: когда загрузка работает, а RUN apt-get — нет
Прокси демона не применяется автоматически к контейнерам сборки. Нужно передать аргументы прокси и объявить их в Dockerfile.
FROM debian:bookworm-slim
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && rm -rf /var/lib/apt/lists/*
Сборка:
docker build --build-arg HTTP_PROXY=http://user:[email protected]:3128 --build-arg HTTPS_PROXY=http://user:[email protected]:3128 --build-arg NO_PROXY=localhost,127.0.0.1 -t myapp .
Важно: значения --build-arg могут быть видны в истории образа и логах сборки. Никогда не встраивайте учётные данные в финальный образ. Используйте многоэтапные сборки и сбрасывайте аргументы перед финальным этапом либо применяйте секретные монтирования BuildKit для учётных данных.
Прокси для отдельного контейнера: установка переменных окружения во время выполнения
Для приложений, которые читают переменные окружения прокси, задайте их при запуске контейнера:
docker run --rm -e HTTP_PROXY=http://proxy.example:3128 -e HTTPS_PROXY=http://proxy.example:3128 -e NO_PROXY=localhost,127.0.0.1 myapp
В Docker Compose:
services:
app:
image: myapp
environment:
HTTP_PROXY: http://proxy.example:3128
HTTPS_PROXY: http://proxy.example:3128
NO_PROXY: localhost,127.0.0.1,.internal.example
Не каждое приложение учитывает эти переменные. Некоторые читают только http_proxy в нижнем регистре, некоторые вообще игнорируют NO_PROXY, а у некоторых есть собственный файл конфигурации. Всегда сверяйтесь с документацией приложения.
SOCKS5: почему прокси-переменные Docker его не принимают
Прокси-переменные демона Docker и --build-arg ожидают URL прокси HTTP или HTTPS. socks5:// не является поддерживаемой схемой для демона. Если ваш прокси-сервис предоставляет только конечную точку SOCKS5, у вас есть три практических варианта:
- Запустить локальный мост HTTP-to-SOCKS5. Небольшой форвардер слушает
127.0.0.1:3128и перенаправляет трафик на ваш SOCKS5-прокси. Затем укажите вHTTP_PROXYDocker адрес этого моста. Так учётные данные SOCKS5 не попадут в окружение Docker. - Использовать динамическое перенаправление SSH плюс мост.
ssh -D 1080даёт вам локальный SOCKS5-прокси; мост преобразует его в HTTP для Docker. Это хорошо работает, когда у вас уже есть SSH-доступ к удалённому хосту. - Настроить приложение внутри контейнера на прямое использование SOCKS5. Многие инструменты (curl, requests, git) поддерживают
socks5h://изначально. Это полностью обходит настройки прокси Docker и влияет только на это приложение.
Пример: проверка SOCKS5 изнутри контейнера без моста с помощью curl. В Linux добавьте --add-host=host.docker.internal:host-gateway, чтобы контейнер мог достучаться до прокси, запущенного на хосте.
docker run --rm --add-host=host.docker.internal:host-gateway curlimages/curl:latest --socks5-hostname host.docker.internal:1080 https://ifconfig.me
--socks5-hostname отправляет имя хоста на прокси для разрешения DNS, что позволяет избежать утечек DNS. Если использовать --socks5, curl разрешает DNS локально и только туннелирует TCP-соединение — распространённый источник неверной геолокации и утечек.
Для кода приложения схема socks5h часто понятнее:
curl --proxy socks5h://user:[email protected]:1080 https://ifconfig.me
Проверка, что прокси действительно используется (и выявление утечек)
После настройки проверьте на каждом уровне:
- Демон:
docker info | grep -i proxyпоказывает переменные. Затемdocker pullдолжен обращаться к прокси. Также можно проверить логи самого прокси на наличие CONNECT-запроса кregistry-1.docker.io:443. - Сборка: добавьте шаг
RUN, который выводит наблюдаемый IP:RUN curl -s https://ifconfig.me || true. Если IP — ваш реальный, сборка не идёт через прокси. Удалите эту строку перед выпуском. - Контейнер:
docker exec -it <container> sh -c 'curl -s https://ifconfig.me'и сравните с вашим реальным IP. - DNS: HTTP-прокси обычно разрешают DNS на стороне прокси для HTTPS (через CONNECT), но обычные HTTP-запросы могут раскрывать DNS, если клиент разрешает локально. SOCKS5 с
socks5hвсегда разрешает удалённо. Если DNS важен, проверьте с помощью DNS leak checker или просмотрите логи прокси.
Частые ошибки при работе с Docker и прокси
NO_PROXYне работает автоматически. Если ваш внутренний реестр или служба на хосте проксируются без необходимости, добавьте их вNO_PROXY. Включитеlocalhost,127.0.0.1и любые внутренние домены.- Верхний и нижний регистр. Некоторые инструменты читают
HTTP_PROXY, другие —http_proxy. Если не уверены, задайте оба. В DockerfileARG HTTP_PROXYдостаточно, чтобы процесс сборки читал вариант в верхнем регистре; добавьтеARG http_proxy, если конкретному инструменту нужен нижний регистр. - Учётные данные в истории сборки. Значения
--build-argмогут появляться вdocker history. Используйте секретные монтирования BuildKit (--mount=type=secret) для токенов и паролей. - Docker Desktop против демона Linux. В Linux вы редактируете systemd; в Docker Desktop используете графический интерфейс или
settings.json. Не считайте, что руководство для Linux применимо к Docker Desktop. - IPv6 и dual-stack. Если ваш прокси поддерживает только IPv4, заставьте контейнер или демон предпочитать IPv4. Некоторым инструментам нужен явный флаг.
Практический рабочий процесс для ограниченных или фильтруемых сетей
Если вы работаете из сети, где доступ к реестру медленный, ограниченный или фильтруемый — что часто встречается в некоторых корпоративных и национальных сетях — начните с прокси на уровне демона, чтобы загрузка образов работала. Затем добавьте аргументы времени сборки для менеджеров пакетов. Наконец, задайте переменные окружения времени выполнения только для контейнеров, которым нужен исходящий трафик через прокси. Если ваша единственная конечная точка прокси — SOCKS5, запустите локальный мост и укажите на него HTTP-переменные прокси Docker, либо оставьте SOCKS5 внутри контейнера для приложений, которые поддерживают его напрямую.
Такой многоуровневый подход позволяет не отправлять весь трафик контейнеров через прокси, когда через него должны идти только загрузка образов и шаги сборки. Он также уменьшает количество мест, где хранятся учётные данные.
Главное
Настройка прокси в Docker — это не одна настройка; это настройка демона, аргумент времени сборки и переменная окружения отдельного контейнера. SOCKS5 поддерживается только там, где его поддерживает приложение — демон Docker — нет. Настраивая каждый уровень осознанно и проверяя с помощью docker info, тестовой загрузки и проверки IP внутри контейнера, вы сможете поддерживать работу сборок без утечек DNS и без встраивания учётных данных в образы.