0

Настройка Nginx в качестве обратного прокси-сервера для развертывания нескольких сервисов на одном сервере с помощью Docker

Чтобы легко начать работу с этой статьей, вам потребуются следующие знания. Но вы можете обойтись и без них.

  • Система/сервер Linux.
  • Знакомство с командами и терминалом Linux.
  • Базовые знания Docker.
  • На вашем сервере Linux должны быть установлены Docker и Docker Compose. Прочтите нашу статью по установке Docker и Docker Compose на CentOS.
  • Вы также должны владеть доменом (чтобы вы могли настраивать службы на поддоменах).

Мы использовали domain.ru в качестве примера доменного имени в статье. Убедитесь, что вы изменили его в соответствии с вашими собственными доменами или субдоменами.

Кроме вышеперечисленного, убедитесь также в следующем:

Измените записи DNS вашего домена

На панели записи A/AAAA или CNAME вашего поставщика доменного имени убедитесь, что и домен, и субдомены (включая www) указывают на IP-адрес вашего сервера.

Это пример для справки:

Имя хостаIP адресTTL
domain.ru172.173.32.178По умолчанию
*172.173.32.178По умолчанию
sub0.domain.ru172.173.32.178По умолчанию
sub1.domain.ru172.173.32.178По умолчанию

Своп

Чтобы убедиться, что все ваши контейнерные приложения удобны и никогда не исчерпывают память после их развертывания, у вас должно быть необходимое пространство подкачки в вашей системе.

Вы всегда можете настроить подкачку в соответствии с доступной оперативной памятью в вашей системе. Вы можете выбрать пространство подкачки на основе набора контейнеров приложений на одном сервере и оценки их совокупного использования ОЗУ.

Шаг 1. Настройте контейнер обратного прокси Nginx

Начните с настройки обратного прокси-сервера 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"

Теперь давайте пройдемся по важным частям файла создания:

  • Вы объявили четыре тома: html, dhparam, vhost и certs. Это постоянные данные, которые вы определенно захотите сохранить даже после того, как контейнер вышел из строя. html и vhost будут очень важны в следующем развертывании контейнера Let’s Encrypt. Они созданы для совместной работы.
  • Сокет docker монтируется внутри контейнера только для чтения. Это необходимо для обратного прокси-контейнера для создания файлов конфигурации nginx, обнаружения других контейнеров с определенной переменной среды.
  • Для политики перезапуска установлено значение always. Другие варианты включают on-failure и unless-stopped. В этом случае всегда казалось более подходящим.
  • Порты 80 и 443 привязаны к хосту для http и https соответственно.
  • Наконец, он использует другую сеть, а не мостовую сеть по умолчанию.

Использование сети, определяемой пользователем, очень важно. Это поможет изолировать все контейнеры, которые должны быть проксированы, а также позволит обратному прокси-контейнеру перенаправлять клиентов в их желаемые/предполагаемые контейнеры, а также позволит контейнерам взаимодействовать друг с другом (что невозможно с сетью моста по умолчанию. если iccне установлено значение trueдля демона).

Имейте в виду, что YML очень требователен к табуляциям и отступам.

Шаг 2. Настройте контейнер для автоматического создания сертификата SSL

Для этого вы можете использовать образ контейнера 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"

В этом определении услуги:

  • Вы используете те же самые тома, что и для контейнера обратного прокси. html и vhost — совместное использование томов необходимы для ACME Challenge of letsencrypt. Этот контейнер будет генерировать сертификаты внутри /etc/nginx/certs, в контейнере. Вот почему вы разделяете этот том со своим обратным прокси-контейнером. Том dhparam будет содержать файл dhparam. Сокет монтируется для обнаружения других контейнеров с определенной переменной среды.
  • Здесь вы определили две переменные среды. В точки переменной NGINX_PROXY_CONTAINER для обратного прокси — контейнера. Задайте его имя контейнера. DEFAULT_EMAIL — это адрес электронной почты, который будет использоваться при создании сертификатов для каждого домена/поддомена.
  • Параметр depends_on установлен таким образом, что эта служба сначала ожидает запуска обратного прокси-сервера, а затем и только тогда он запускается.
  • Наконец, этот контейнер также находится в одной сети. Это необходимо для связи двух контейнеров.

Шаг 3. Завершите создание файла для докеров

После того, как определения сервисов созданы, заполните файл 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


Шаг 4. Запустите другие сервисные контейнеры с обратным прокси

Процесс настройки других контейнеров, чтобы их можно было проксировать, ОЧЕНЬ прост.

Определите правильные переменные среды

Контейнер, который будет обслуживать интерфейс, должен будет определить две переменные среды.

  • VIRTUAL_HOST: для создания конфигурации обратного прокси
  • LETSENCRYPT_HOST: для создания необходимых сертификатов

Вы можете запустить веб-службу через контейнер докеров с обратным прокси следующим образом (не копируйте и вставляйте его):

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

Если обратный прокси-контейнер не может обнаружить порт, вы можете определить другую переменную среды VIRTUAL_PORT с именем порта, обслуживающего интерфейс, или любую другую службу, которую вы хотите проксировать, например «80» или «7765».

Установите Let’s Encrypt для конкретного контейнера

Вы можете переопределить переменную 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, работающий в другом субдомене на том же сервере.

С помощью этого метода вы можете развертывать разные веб-приложения на одном сервере, обслуживаемом в разных субдоменах, что очень удобно.

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:398 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(845): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(418): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 398