Что такое обратный прокси? Обратный прокси-сервер – это своего рода сервер, который находится перед многими другими серверами и перенаправляет клиентские запросы на соответствующие серверы. Затем ответ от сервера также принимается и пересылается прокси-сервером клиенту.
Зачем вам такая установка? Для этого есть несколько веских причин. Эту настройку можно использовать для настройки балансировщика нагрузки, кэширования или для защиты от атак.
Мы не будем здесь вдаваться в подробности. Вместо этого мы покажем вам, как можно использовать концепцию обратного прокси для настройки нескольких служб на одном сервере.
Возьмите то же изображение, что вы видели выше. Что вы можете сделать, так это запустить сервер Ngnix в Docker контейнере в режиме обратного прокси. Другие веб-службы также могут запускаться в своих собственных контейнерах.
Контейнер Nginx будет настроен таким образом, чтобы он знал, какая веб-служба в каком контейнере работает.
Это хороший способ сэкономить на размещении каждой службы на отдельном сервере. У вас может быть несколько служб, работающих на одном сервере Linux, благодаря обратному прокси-серверу.
Позвольте нам показать вам, как приступить к настройке вышеупомянутой установки.
С помощью этих шагов вы можете установить несколько контейнеров веб-приложений, работающих под Nginx, причем каждый автономный контейнер соответствует своему собственному домену или субдомену.
Во-первых, давайте посмотрим, что вам нужно, чтобы следовать этой статьи.
Чтобы легко начать работу с этой статьей, вам потребуются следующие знания. Но вы можете обойтись и без них.
Мы использовали domain.ru в качестве примера доменного имени в статье. Убедитесь, что вы изменили его в соответствии с вашими собственными доменами или субдоменами.
Кроме вышеперечисленного, убедитесь также в следующем:
Измените записи DNS вашего домена
На панели записи A/AAAA или CNAME вашего поставщика доменного имени убедитесь, что и домен, и субдомены (включая www) указывают на IP-адрес вашего сервера.
Это пример для справки:
Имя хоста | IP адрес | TTL |
---|---|---|
domain.ru | 172.173.32.178 | По умолчанию |
* | 172.173.32.178 | По умолчанию |
sub0.domain.ru | 172.173.32.178 | По умолчанию |
sub1.domain.ru | 172.173.32.178 | По умолчанию |
Чтобы убедиться, что все ваши контейнерные приложения удобны и никогда не исчерпывают память после их развертывания, у вас должно быть необходимое пространство подкачки в вашей системе.
Вы всегда можете настроить подкачку в соответствии с доступной оперативной памятью в вашей системе. Вы можете выбрать пространство подкачки на основе набора контейнеров приложений на одном сервере и оценки их совокупного использования ОЗУ.
Начните с настройки обратного прокси-сервера nginx. Создайте каталог с именем “reverse-proxy” и переключитесь в него:
mkdir reverse-proxy && cd reverse-proxy
Создайте файл с именем docker-compose.yml, откройте его в своем любимом текстовом редакторе на базе терминала, таком как Vim или Nano.
Для обратного прокси-сервера nginx мы будем использовать образ jwilder/nginx-proxy. Скопируйте и вставьте в файл docker-compose.yml следующее:
version: "3.7" services: reverse-proxy: image: "jwilder/nginx-proxy:latest" container_name: "reverse-proxy" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/tmp/docker.sock:ro" restart: "always" networks: - "net" ports: - "80:80" - "443:443"
Теперь давайте пройдемся по важным частям файла создания:
Использование сети, определяемой пользователем, очень важно. Это поможет изолировать все контейнеры, которые должны быть проксированы, а также позволит обратному прокси-контейнеру перенаправлять клиентов в их желаемые/предполагаемые контейнеры, а также позволит контейнерам взаимодействовать друг с другом (что невозможно с сетью моста по умолчанию. если iccне установлено значение trueдля демона).
Имейте в виду, что YML очень требователен к табуляциям и отступам.
Для этого вы можете использовать образ контейнера jrcs/letsencrypt-nginx-proxy-companion.
В том же файле docker-compose.yml, который вы использовали ранее, добавьте следующие строки:
letsencrypt: image: "jrcs/letsencrypt-nginx-proxy-companion:latest" container_name: "letsencrypt-helper" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/var/run/docker.sock:ro" environment: NGINX_PROXY_CONTAINER: "reverse-proxy" DEFAULT_EMAIL: "user@domain.ru" restart: "always" depends_on: - "reverse-proxy" networks: - "net"
В этом определении услуги:
После того, как определения сервисов созданы, заполните файл docker-compose следующими строками:
volumes: certs: html: vhost: dhparam: networks: net: external: true
Сеть net настроена на внешнюю, потому что прокси-контейнеры также должны будут использовать эту сеть. И если мы оставим сеть для создания docker-comspose, имя сети будет зависеть от текущего каталога. Это создаст сеть со странным названием.
Помимо этого, другие контейнеры все равно должны будут установить эту сеть как внешнюю, в противном случае эти файлы компоновки также должны будут находиться в этом же каталоге, ни один из которых не является идеальным.
Поэтому создайте сеть, используя
docker network create net
Ниже приводится все содержимое файла docker-compose.yml.
version: "3.7" services: reverse-proxy: image: "jwilder/nginx-proxy:latest" container_name: "reverse-proxy" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/tmp/docker.sock:ro" restart: "always" networks: - "net" ports: - "80:80" - "443:443" letsencrypt: image: "jrcs/letsencrypt-nginx-proxy-companion:latest" container_name: "letsencrypt-helper" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/var/run/docker.sock:ro" environment: NGINX_PROXY_CONTAINER: "reverse-proxy" DEFAULT_EMAIL: "user@domain.ru" restart: "always" depends_on: - "reverse-proxy" networks: - "net" volumes: certs: html: vhost: dhparam: networks: net: external: true
Наконец, вы можете развернуть эти два контейнера (Ngnix и Let’s Encrypt) с помощью следующей команды:
docker-compose up -d
Процесс настройки других контейнеров, чтобы их можно было проксировать, ОЧЕНЬ прост.
Контейнер, который будет обслуживать интерфейс, должен будет определить две переменные среды.
Вы можете запустить веб-службу через контейнер докеров с обратным прокси следующим образом (не копируйте и вставляйте его):
docker run --name service_container_name --network net -e VIRTUAL_HOST="sub0.domain.ru" -e LETSENCRYPT_HOST="sub0.domain.ru" -d service_image
Мы покажем это с двумя экземплярами развертывания Nextcloud через мгновение. Позвольте нам сначала рассказать вам, что вы здесь делаете.
В контейнере может отсутствовать порт, обслуживающий интерфейс. Контейнер обратного прокси-сервера автоматически обнаружит это.
Если обратный прокси-контейнер не может обнаружить порт, вы можете определить другую переменную среды VIRTUAL_PORT с именем порта, обслуживающего интерфейс, или любую другую службу, которую вы хотите проксировать, например «80» или «7765».
Вы можете переопределить переменную DEFAULT_EMAIL и установить конкретный адрес электронной почты для сертификата (ов) домена/поддомена конкретного контейнера/веб-службы, установив идентификатор электронной почты в переменную среды LETSENCRYPT_EMAIL. Это работает для каждого контейнера.
Теперь, когда вы знаете все это, позвольте мне показать вам команду, которая развертывает экземпляр Nextcloud, который будет проксироваться с помощью прокси-контейнера nginx и будет иметь включенный TLS (SSL/HTTPS).
Это НЕ ИДЕАЛЬНОЕ развертывание. Следующая команда используется только в демонстрационных целях.
docker run --name nextcloud --network net -e VIRTUAL_HOST="sub0.domain.ru" -e LETSENCRYPT_HOST="sub0.domain.ru" -d nextcloud:19.0.2
В этом примере вы использовали ту же сеть, что и обратные прокси-контейнеры, определили две переменные среды с соответствующими поддоменами (установите свои соответственно). Через пару минут вы должны увидеть, что Nextcloud работает на sub0.domain.ru. Откройте его в браузере, чтобы проверить.
Вы можете развернуть другой экземпляр Nextcloud, как этот, в другом субдомене, например:
docker run --name anothernextcloud --network net -e VIRTUAL_HOST="sub1.domain.ru" -e LETSENCRYPT_HOST="sub1.domain.ru" -d nextcloud:19.0.2
Теперь вы должны увидеть другой экземпляр Nextcloud, работающий в другом субдомене на том же сервере.
С помощью этого метода вы можете развертывать разные веб-приложения на одном сервере, обслуживаемом в разных субдоменах, что очень удобно.
Было бы круто нарисовать небольшую схемку визуализации контейнеров, для более быстрого понимания что-куда. Спасибо за статью, познавательно.
Спасибо за статью.
Хочу использовать данное решение как обратный прокси для Docker приложения mailtrain (https://github.com/Mailtrain-org/mailtrain).
Как на этапе 4 запускать mailtrain, если он сам запускается с помощью docker-compose?
Вижу решение в виде объединения файлов docker-compose.yml.
Но как правильно расписать сети для каждого контейнера и последовательность запуска, а также запуск:
Попытка последовательного запуска:
С предварительно внесённым:
networks:
default:
external:
name: net
Ситуацию не спасает, порты 80,443, 3000, 3004 по прежнему закрыты.