GeekProxy в Docker
В Docker три разных настройки прокси, и их путают постоянно. Одна для приложений внутри контейнеров и сборок, другая для разового docker run, третья для демона, который тянет образы. В гайде все три, с ключами конфигов ровно в том написании, что в документации Docker.
Что нужно: активный план GeekProxy и данные прокси из кабинета. Контейнерная часть занимает пять минут, для демона нужен Linux-хост и перезапуск.
Получить прокси1 Перед началом
Сначала разберитесь с тремя слоями. Прокси не в том слое ничего не делает, а виноватым окажется прокси.
- Ключ
proxiesв~/.docker/config.jsonзадаёт переменные окружения прокси внутри новых контейнеров и сборок. Документация прямо говорит, что ни Docker CLI, ни сам Engine его не используют --envуdocker runи--build-argуdocker buildделают то же самое для одного контейнера или одной сборки/etc/docker/daemon.json(или drop-in для systemd) объясняет демону, как ходить в Docker Hub и другие реестры. Это pull, push и swarm, а не то, что делает ваше приложение
Во всех трёх местах прокси это URL HTTP-прокси с логином и паролем внутри. SOCKS в документации Docker Engine нет вообще. Docker Desktop показывает SOCKS5 в своих настройках Proxies, но только с подпиской Business. Внутри контейнера SOCKS зависит от приложения, которое читает ALL_PROXY, так что честный ответ про SOCKS5 с паролем такой: на уровне Docker его нет. Берите HTTP-порт. И приложения внутри слушаются переменных, только если умеют читать HTTP_PROXY и компанию. curl, pip, apt и большинство HTTP-библиотек умеют, программа со своей настройкой прокси их проигнорирует.
Что понадобится
- Активный план GeekProxy (датацентр, ISP или резидентские)
- Данные прокси из кабинета: хост, порт, логин, пароль
- Docker Desktop на macOS или Windows для контейнеров и сборок; Linux-хост с Docker Engine для части про демон
- Поле Откуда взять
- Протокол HTTP
- Хост IP или имя шлюза из кабинета
- Порт из кабинета
- Логин из кабинета
- Пароль из кабинета
2 Где взять данные прокси
- Войдите в кабинет GeekProxy
- Откройте план. У планов с оплатой за IP (датацентр, ISP) список адресов, порты, логин и пароль лежат прямо на карточке, а кнопка Export отдаёт весь список текстом
- У резидентских и мобильных планов нажмите Options. Панель Proxy Configuration соберёт строку логина с вашей страной, городом и настройками сессии. Готовую строку копируйте из Proxy List
Посмотрите на пароль, прежде чем куда-то его вставлять. Символы вроде @, : или # внутри URL кодируются процентами, а в юнитах systemd сверху ещё нужен двойной %% (раздел 5). План в режиме белого списка снимает вопрос: URL тогда просто http://IP:PORT.
3 Контейнеры и сборки: config.json
Это настройка для парсера или бота, который живёт в контейнере. Откройте ~/.docker/config.json (если нет, создайте) и добавьте блок proxies с записью default.
{
"proxies": {
"default": {
"httpProxy": "http://LOGIN:PASSWORD@IP:PORT",
"httpsProxy": "http://LOGIN:PASSWORD@IP:PORT",
"noProxy": "localhost,127.0.0.0/8"
}
}
}
Каждый ключ превращается в пару переменных окружения внутри контейнера. httpProxy задаёт HTTP_PROXY и http_proxy, httpsProxy пару HTTPS_PROXY, noProxy пару NO_PROXY. Есть ещё allProxy и ftpProxy, если приложению надо. При docker build те же значения становятся аргументами сборки.
Одна деталь ловит многих. Значение httpsProxy это прокси для целей на https://, а схема в нём описывает путь до прокси. Порты GeekProxy это обычные HTTP-прокси, поэтому оба ключа начинаются с http://. В примере из документации Docker стоит https:// прокси на порту 3129, то есть прокси с TLS, это не наш случай.
Файл читается при сохранении. Без перезапуска. Но действует он только на контейнеры и сборки, запущенные после сохранения; работающие контейнеры остаются со старым окружением.
Документация предупреждает: эти значения лежат открытым текстом в конфигурации контейнера. Кто угодно с доступом к remote API прочитает их через docker inspect, а docker commit запечёт их в образ. На общем хосте лучше план с белым списком IP и URL без логина и пароля.
4 Один контейнер или одна сборка
Для разового запуска конфиг не нужен. Передайте переменные через --env. Самое быстрое доказательство: образ curl запрашивает ipinfo.
docker run --rm \ --env HTTPS_PROXY="http://LOGIN:PASSWORD@IP:PORT" \ --env HTTP_PROXY="http://LOGIN:PASSWORD@IP:PORT" \ curlimages/curl -s https://ipinfo.io/json docker build --build-arg HTTPS_PROXY="http://LOGIN:PASSWORD@IP:PORT" .
У сборок свои правила. HTTP_PROXY, HTTPS_PROXY, NO_PROXY, ALL_PROXY и их двойники в нижнем регистре это предопределённые аргументы сборки, объявлять их через ARG не нужно. Живут они только в контейнере сборки и в итоговый образ не попадают. По умолчанию их ещё и не видно в docker history. Допишите в Dockerfile явный ARG HTTP_PROXY, и защита пропадёт: значение появится в истории, а его смена сбросит кэш.
Никогда не задавайте прокси для сборки через ENV. В документации об этом одна строка. Причина очевидна, стоит задуматься: ENV запекает логин и пароль в каждый слой и в каждый контейнер из этого образа.
5 Демон: загрузка образов
Если сам хост должен тянуть образы через прокси, настраивайте демон. Документация рекомендует /etc/docker/daemon.json и отмечает, что настройка демона важнее переменных окружения.
{
"proxies": {
"http-proxy": "http://LOGIN:PASSWORD@IP:PORT",
"https-proxy": "http://LOGIN:PASSWORD@IP:PORT",
"no-proxy": "localhost,127.0.0.0/8"
}
}
Обратите внимание: здесь ключи через дефис, а в config.json в camelCase. Разные файлы, разное написание, одна идея. Дальше sudo systemctl restart docker.
Старый способ тоже работает: drop-in для systemd в /etc/systemd/system/docker.service.d/http-proxy.conf со строками Environment= для HTTP_PROXY, HTTPS_PROXY и NO_PROXY. Спецсимволы в значении, документация перечисляет #?!()[]{}, экранируются дважды через %%. После правки выполните sudo systemctl daemon-reload, перезапустите docker и проверьте через sudo systemctl show --property=Environment docker. В rootless-режиме drop-in лежит в ~/.config/systemd/user/docker.service.d/, а команды идут с systemctl --user.
[Service] Environment="HTTP_PROXY=http://LOGIN:PASSWORD@IP:PORT" Environment="HTTPS_PROXY=http://LOGIN:PASSWORD@IP:PORT" Environment="NO_PROXY=localhost,127.0.0.1"
Docker Desktop
Desktop игнорирует прокси из daemon.json. Его место: Settings, Resources, Proxies, с режимами System proxy, No proxy и Manual configuration. В ручном режиме задаются URL для web server (HTTP) и secure web server (HTTPS) в форме http://proxy:port плюс список исключений. SOCKS5 там требует подписки Business, а про логин и пароль в ручном URL страница молчит. Для контейнеров ничего из этого не нужно: config.json на Desktop работает как обычно.
6 Проверка работы
Две проверки, именно в таком порядке. Сначала убедитесь, что переменные доехали. Команда из документации: docker run --rm alpine sh -c 'env | grep -i _PROXY'; с config.json из раздела 3 она печатает три пары. Потом запросите https://ipinfo.io/json из контейнера, например строкой с curlimages/curl выше, но уже без флагов --env. Поле ip должно показать адрес прокси, а не хоста. На ISP или датацентре это адрес из кабинета, на Residential или Turbo любой адрес из пула в выбранной стране.
7 Какой продукт GeekProxy подходит
Контейнер ответа не меняет, его определяет приложение внутри. Парсеру в контейнере нужны Residential Turbo или Residential Flex: ротация для охвата, sticky, когда сценарий входа должен держаться одного адреса. Боту или API-клиенту, которому неделями нужен один IP, подойдут статический ISP или датацентр IPv4: без счётчика трафика, а в режиме белого списка ещё и без логина с паролем в конфиге. Flex работает только по TCP, HTTP-клиенты этого не замечают. Загрузка образов через прокси это задача корпоративного egress, а не выбора продукта. Если всё же нужен фиксированный IP для доступа к реестру, один датацентровый адрес самый дешёвый путь.
8 Частые проблемы
Контейнер по-прежнему показывает мой IP
Либо контейнер запущен до сохранения config.json, либо приложение внутри не читает HTTP_PROXY. Перезапустите контейнер и сделайте проверку через env | grep. Переменные на месте, а IP не меняется, значит у приложения своя настройка прокси, и задавать нужно её.
docker pull идёт без прокси, а приложение нет, или наоборот
Прокси демона и прокси контейнера это разные вещи. daemon.json отвечает за загрузку образов, config.json за то, что крутится внутри. Нужно и то и другое, задавайте оба.
На Mac настройки прокси в daemon.json игнорируются
Docker Desktop их не читает. Для трафика хоста используйте Settings, Resources, Proxies, для контейнеров config.json.
Демон не принимает пароль со спецсимволами
В юните systemd каждый из #?!()[]{} требует двойного экранирования %%, а внутри любого URL сначала действует обычное процентное кодирование. План с белым списком IP обходит это целиком.
Часть хостов должна идти мимо прокси, но no_proxy ведёт себя странно
Документация честно признаёт: стандарта на то, как клиенты читают эти переменные, нет. NO_PROXY у демона принимает префиксы IP, домены с точкой в начале и без, * и конкретные порты. Приложения внутри контейнеров разбирают его каждое по-своему, так что проверяйте конкретное приложение.
Прокси для Docker
Ротируемые резидентские для парсеров в контейнерах, статические ISP и датацентр для ботов и API-клиентов.
Заказать