Настройка прокси в Docker позволяет контейнерам и Docker-демону маршрутизировать сетевой трафик через промежуточный сервер, что достигается конфигурацией переменных окружения на этапе сборки образа или запуска контейнера, а также изменением настроек демона Docker.
Применение прокси в Docker
Прокси-серверы используются в Docker для различных целей:
* Доступ к внешним ресурсам: Контейнерам требуется доступ к интернету для загрузки пакетов, библиотек или данных из внешних API. В корпоративных сетях такой доступ часто регулируется через прокси.
* Геотаргетинг и обход блокировок: Для работы с сервисами, доступными только в определенных регионах, или для обхода сетевых ограничений.
* Анонимность и безопасность: Скрытие реального IP-адреса источника запросов, а также фильтрация трафика.
* Мониторинг и логирование: Централизованный контроль и запись всего исходящего трафика из контейнеров.
Конфигурация прокси может быть выполнена на нескольких уровнях:
1. На уровне отдельного контейнера: Передача переменных окружения при запуске.
2. На уровне Dockerfile: Включение переменных окружения в образ на этапе сборки.
3. На уровне Docker Compose: Управление переменными окружения для группы сервисов.
4. На уровне демона Docker: Для операций docker pull, docker build и других, выполняемых самим демоном.
Настройка прокси для отдельного контейнера
Наиболее простой способ настроить прокси для одного контейнера — это передать соответствующие переменные окружения при его запуске. Стандартные переменные окружения для прокси: HTTP_PROXY, HTTPS_PROXY, FTP_PROXY, и NO_PROXY. Регистр важен, поэтому часто указывают обе формы: HTTP_PROXY и http_proxy.
Передача переменных окружения при запуске
Для запуска контейнера с настроенным прокси используется флаг -e команды docker run.
docker run -it \
-e HTTP_PROXY="http://user:password@proxy.example.com:8080" \
-e HTTPS_PROXY="http://user:password@proxy.example.com:8080" \
-e NO_PROXY="localhost,127.0.0.1,*.internal.com" \
alpine/git sh
В этом примере:
* HTTP_PROXY и HTTPS_PROXY указывают адрес прокси-сервера, включая порт и, опционально, учетные данные.
* NO_PROXY определяет список хостов или доменов, для которых прокси использоваться не будет. Разделитель — запятая. Поддерживаются подстановочные знаки (*).
Проверка работы прокси в контейнере
После запуска контейнера можно проверить, что переменные окружения установлены и прокси используется.
# Внутри запущенного контейнера
env | grep PROXY
# Проверка IP-адреса через внешний сервис
curl -s ifconfig.me
Если прокси работает корректно, curl должен показать IP-адрес прокси-сервера (или его исходящего интерфейса), а не IP-адрес хостовой машины.
Настройка прокси в Dockerfile
Конфигурация прокси в Dockerfile необходима, когда образ должен использовать прокси для загрузки зависимостей или пакетов на этапе сборки (например, apt-get update, npm install, pip install).
Использование ENV для прокси на этапе сборки
Переменные ENV устанавливают переменные окружения, которые будут доступны как на этапе сборки, так и в конечном образе.
# Dockerfile
FROM ubuntu:latest
# Установка переменных прокси
ENV HTTP_PROXY="http://proxy.example.com:8080"
ENV HTTPS_PROXY="http://proxy.example.com:8080"
ENV NO_PROXY="localhost,127.0.0.1"
# Пример использования прокси для установки пакетов
RUN apt-get update && apt-get install -y curl
# Переменные прокси могут быть удалены, если они не нужны в конечном образе
# ENV HTTP_PROXY=""
# ENV HTTPS_PROXY=""
CMD ["bash"]
Особенности ENV:
* Значения переменных ENV записываются в кэш образа.
* Если прокси-сервер требует аутентификации, учетные данные будут встроены в образ, что является потенциальной угрозой безопасности.
Использование ARG для прокси на этапе сборки
ARG позволяет передавать переменные, которые доступны только на этапе сборки и не сохраняются в конечном образе. Это предпочтительный метод для передачи чувствительных данных, таких как учетные данные прокси.
# Dockerfile
FROM ubuntu:latest
# Объявление ARG для прокси
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
# Установка переменных окружения для использования на этапе сборки
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
ENV NO_PROXY=$NO_PROXY
# Пример использования прокси для установки пакетов
RUN apt-get update && apt-get install -y curl
# Сброс переменных прокси, чтобы они не попали в конечный образ
# Это важно для безопасности и уменьшения размера образа
ENV HTTP_PROXY=""
ENV HTTPS_PROXY=""
ENV NO_PROXY=""
CMD ["bash"]
Сборка образа с ARG:
docker build \
--build-arg HTTP_PROXY="http://user:password@proxy.example.com:8080" \
--build-arg HTTPS_PROXY="http://user:password@proxy.example.com:8080" \
--build-arg NO_PROXY="localhost,127.0.0.1" \
-t my-app-with-proxy .
Особенности ARG:
* Значения ARG не сохраняются в слоях образа после завершения этапа сборки, если явно не переназначены в ENV.
* Позволяет передавать чувствительные данные без их сохранения в конечном образе.
Настройка прокси с Docker Compose
Docker Compose упрощает управление несколькими контейнерами и их конфигурацией, включая прокси.
Конфигурация прокси через environment
Для сервисов Docker Compose переменные окружения можно указать в секции environment файла docker-compose.yml.
# docker-compose.yml
version: '3.8'
services:
my-app:
build: .
environment:
- HTTP_PROXY=http://user:password@proxy.example.com:8080
- HTTPS_PROXY=http://user:password@proxy.example.com:8080
- NO_PROXY=localhost,127.0.0.1,my-other-service
# Другие настройки сервиса
В этом примере, если my-app использует build: ., то прокси будет действовать только на этапе запуска контейнера. Чтобы прокси работал и на этапе сборки образа (если Dockerfile находится в текущем каталоге), необходимо использовать args в секции build.
Конфигурация прокси для этапа сборки с Docker Compose
Если сервис собирает образ из Dockerfile, можно передать build-arg через секцию build в docker-compose.yml.
# docker-compose.yml
version: '3.8'
services:
my-app:
build:
context: .
args:
HTTP_PROXY: http://user:password@proxy.example.com:8080
HTTPS_PROXY: http://user:password@proxy.example.com:8080
NO_PROXY: localhost,127.0.0.1,my-other-service
environment: # Эти переменные будут доступны в рантайме
- HTTP_PROXY=http://user:password@proxy.example.com:8080
- HTTPS_PROXY=http://user:password@proxy.example.com:8080
- NO_PROXY=localhost,127.0.0.1,my-other-service
И соответствующий Dockerfile (как в примере с ARG выше):
# Dockerfile
FROM ubuntu:latest
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
ENV NO_PROXY=$NO_PROXY
RUN apt-get update && apt-get install -y curl
ENV HTTP_PROXY=""
ENV HTTPS_PROXY=""
ENV NO_PROXY=""
CMD ["bash"]
Настройка прокси для Docker Daemon
Docker-демон (процесс dockerd) также может требовать прокси для выполнения операций, таких как docker pull (загрузка образов) или docker build (если сборка образа требует доступа к внешним ресурсам, которые не могут быть настроены в Dockerfile через ARG/ENV).
Конфигурация прокси для демона Docker выполняется через файл ~/.docker/config.json для пользователя или через системные настройки systemd для всего демона.
Конфигурация через ~/.docker/config.json
Этот метод влияет на клиент Docker (docker CLI), а не на сам демон. Он полезен для операций docker build и docker pull, выполняемых из командной строки.
Создайте или отредактируйте файл ~/.docker/config.json:
{
"proxies": {
"default": {
"httpProxy": "http://user:password@proxy.example.com:8080",
"httpsProxy": "http://user:password@proxy.example.com:8080",
"noProxy": "localhost,127.0.0.1,.internal.com"
}
}
}
После изменения файла config.json необходимо перезапустить клиент Docker или терминал, чтобы изменения вступили в силу.
Конфигурация через systemd (для Linux-систем)
Для систем с systemd (большинство современных дистрибутивов Linux) можно настроить прокси для демона Docker, создав файл переопределения для сервиса docker.service.
- Создайте директорию для переопределения:
bash sudo mkdir -p /etc/systemd/system/docker.service.d -
Создайте файл
http-proxy.confв этой директории:
bash sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
Содержимое файла:
ini [Service] Environment="HTTP_PROXY=http://user:password@proxy.example.com:8080" Environment="HTTPS_PROXY=http://user:password@proxy.example.com:8080" Environment="NO_PROXY=localhost,127.0.0.1,.internal.com"
Можно также использоватьEnvironmentFileдля загрузки переменных из отдельного файла, что удобно для управления секретами. -
Перезагрузите конфигурацию
systemdи перезапустите Docker-демон:
bash sudo systemctl daemon-reload sudo systemctl restart docker
После этих шагов демон Docker будет использовать указанный прокси для всех своих сетевых операций.
Таблица сравнения методов настройки прокси
| Метод настройки | Уровень | Применимость | Сохранение в образе | Безопасность учетных данных |
|---|---|---|---|---|
docker run -e |
Контейнер | Только runtime | Нет | Хорошо (не в образе) |
Dockerfile с ENV |
Образ (build & runtime) | Build-time и runtime | Да | Плохо (в образе) |
Dockerfile с ARG |
Образ (только build) | Только build-time | Нет | Хорошо (не в образе) |
docker-compose.yml (env) |
Сервис (runtime) | Только runtime | Нет | Хорошо (не в образе) |
docker-compose.yml (args) |
Сервис (build) | Только build-time | Нет | Хорошо (не в образе) |
~/.docker/config.json |
Docker CLI | docker pull, docker build (cli) |
Нет | Хорошо (на локальной машине) |
systemd для dockerd |
Демон Docker | Все операции демона | Нет | Хорошо (на хост-машине) |
Рекомендации по безопасности
- Избегайте жесткого кодирования учетных данных: Не встраивайте логины и пароли прокси непосредственно в
Dockerfileс помощьюENV. ИспользуйтеARGдля этапа сборки и передавайте их черезbuild-arg. Для runtime используйте переменные окружения, загружаемые из файлов.envили системных секретов. - Используйте
NO_PROXY: Всегда указывайте локальные IP-адреса, адреса внутренних сетей и домены, которые не должны проходить через прокси. Это повышает производительность и безопасность. - Проверяйте переменные окружения: После настройки убедитесь, что переменные окружения корректно установлены в контейнерах.
- Ограничивайте область действия: Настраивайте прокси только там, где это необходимо. Глобальная настройка на уровне демона может повлиять на все контейнеры.
Устранение неполадок
- Неправильный формат URL: Убедитесь, что URL прокси-сервера указан в правильном формате (
http://user:password@host:port). - Брандмауэр: Проверьте, не блокирует ли брандмауэр хост-системы или сетевого оборудования исходящие соединения к прокси-серверу.
- Прокси-сервер недоступен: Убедитесь, что прокси-сервер работает и доступен с хост-системы.
- Отсутствие
NO_PROXY: Если контейнер пытается получить доступ к локальному ресурсу через прокси, это может привести к ошибкам. Добавьте соответствующие адреса вNO_PROXY. - Проблемы с DNS: Убедитесь, что DNS-разрешение работает корректно как для прокси-сервера, так и для целевых ресурсов.
Правильная настройка прокси в Docker обеспечивает контролируемый и безопасный доступ контейнеров к внешним ресурсам, что является фундаментальным аспектом при развертывании приложений в корпоративных и производственных средах.