Тривиальный случай: nginx для статики в docker-compose

Docker Registry позволяет хранить готовые Image для своего репозитория на GitLab. Конечно же, можно хранить контейнеры и в Docker Hub, но когда все в одном месте — это удобно. Тем более если репозиторий приватный, то доступ к контейнерам получат только те, у кого есть права.

Nginx как веб и прокси-сервер для Apache в Ubuntu

Apache и Nginx – два самых популярных веб-сервера с открытым исходным кодом. Они которые часто используются для работы с PHP. Их можно использовать для поддержки нескольких веб-сайтов с разными требованиями на одной виртуальной машине. Обычно два веб-сервера в одной системе используют для работы с несколькими IP-адресами или различными портами.

Серверы с поддержкой адресов IPv4 и IPv6 можно настроить для обслуживания веб-сервера Apache по одному протоколу и Nginx – по другому. Но это не очень практично, так как IPv6 до сих пор не получил широкого распространения. Можно также установить другой номер порта для второго веб-сервера, но использовать порты в ссылках очень неудобно (http://your_domain:81).

Этот мануал поможет настроить Nginx как веб-сервер и прокси-сервер для Apache на одном сервере Ubuntu

При этом вам может понадобиться изменить код приложения, чтобы включить поддержку обратного прокси в Apache (особенно это касается сайтов с поддержкой SSL). Чтобы избежать этого, можно установить специальный модуль Apache, mod_rpaf, который переопределяет некоторые переменные среды, благодаря чему Apache может напрямую обслуживать запросы клиентов.

Мы покажем, как разместить четыре домена в рамках одного сервера. Два из них будут обслуживаться Nginx: _domain (стандартный виртуальный хост) и _domain. Другие два обслуживаются Apache: _domain и _domain. Мы также настроим Apache для поддержки PHP-приложений по PHP-FPM, что обеспечивает лучшую производительность по сравнению с mod_php.

Читайте также:  4 способа управлять смартфоном с разбитым экраном через компьютер

Требования

  • Новый сервер Ubuntu , настроенный по этому мануалу.
  • 4 домена, направленные на IP-адрес вашего сервера. Читайте мануал Как настроить имя хоста, чтобы создать необходимые записи А.

Настройки Apache

Тут от настроек не так много, главное установить нужный порт и настроить видимость сервера только внутри себя. Порт 80 мы использовать больше не можем, так как им будет пользоваться nginx поэтому возьмем порт 81.

Редактируем файл /etc/httpd/

#ставим внутренний адрес и меняем порт на 81 Listen 127.0.0.1:81 #KeepAlive запросы позволяют устанавливать постоянные соединения между клиентом и сервером. Это экономит ресурсы на отсутствии повторной установки соединений. KeepAlive Off

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

Создаем виртуальный хост для нашего сайта с минимальными настройками. Это может быть общий файл  или на каждый сайт свой файл.

# Указываем выбранный порт: <VirtualHost 127.0.0.1:81> ServerName ServerAlias DocumentRoot /home/www/html/site CustomLog /var/log/httpd/_ combined ErrorLog /var/log/httpd/_ <Directory «/home/www/htmlsite»> AllowOverride none </Directory> </VirtualHost>

Директива AllowOverride включает использование файла .htaccess. В этом случае при каждом запросе Apache будет обращаться к директории сайта для его поиска. Лучше переместить все настройки в конфигурационный файл немного ускорив обработку.

docker-compose

Итак, главный герой, docker-compose. Эта утилита помогает специфицировать контейнеры в декларативном виде, то есть запуск, остановка и другие задачи выполняются посредством конфигурационного файла (по умолчанию ). Давайте взглянем, каким образом нужно его оформить, чтобы запустить официальный контейнер веб-сервера nginx, который будет отдавать статику из указанной директории. В моём случае я располагаю файл в корневой директории проекта.

version: ‘3’ services: nginx: image: «nginx:latest» ports: «127.0.0.1:8080:80» volumes: «./build:/usr/share/nginx/html:ro»

Выглядит просто, но давайте разберём всё по порядку.

Читайте также:  Как перезагрузить телефон Sony Xperia X, если он завис

version

version: '3' указывает версию конфигурационного файла, на момент написания заметки, 3-я версия является наиболее актуальной.

services

Каждый элемент раздела services отвечает за конкретный сервис. В нашем случае он один, где nginx это просто имя сервиса, ничего более.

image

image: "nginx:latest" специфицирует, из какого образа будет создан контейнер, в данном случае это официальный образ веб-сервера nginx, а :latest это тег образа, который чаще всего отвечает за версию.

ports

— "127.0.0.1:8080:80" отвечает за маппинг 80 порта контейнера на интерфейс 127.0.0.1 и порт 8080 хостовой машины. Иными словами, nginx, слушающий 80-й порт внутри контейнера, позволит нам работать с ним, открывая в браузере адрес 127.0.0.1:8080, или, даже проще, localhost:8080.

volumes

— "./build:/usr/share/nginx/html:ro" определяет маппинг разделов.

  • ./build — директория нашего проекта, в которой лежит собранная версия сайта, то есть статика, которую и необходимо отдавать через веб-сервер.
  • /usr/share/nginx/html — директория внутри контейнера, в которую будет примонтирован раздел с содержимым ./build. Если задаётесь вопросом, почему именно /usr/share/nginx/html, то всё просто, эта директория указана в конфигурации nginx, а конфигурация в свою очередь зашита в базовом образе nginx:latest. Чтобы не собирать руками свой образ со своей конфигурацией, мы просто опираемся на официальный, конфигурация которого уже готова отдавать статику именно из этой директории.
  • ro в конце декларации отвечает за то, что раздел будет работать в режиме read-only для нашего контейнера.

Введение

В предыдущей части мы написали docker-compose файл, в котором настроили запуск сервисов с серверной частью приложения, клиентской частью и базой данных. Теперь же нам необходимо настроить приложение следующим образом:

  • Angular приложение должно быть доступно только по адресу ;
  • серверное api должно принимать запросы по адресу ;
  • должен быть открыт только порт 80.
Читайте также:  CHKDSK /F /R для устранения повреждений файловой системы

Для этого нужно поднять прокси-сервер, который будет принимать все запросы на порту 80 и по хосту ретранслировать запросы на сервис client для и на server для

Самое популярное решение для этих целей — использовать прокси-сервер nginx. Однако в этом проекте я попробую использовать Traefik — молодой реверс-прокси сервер и балансировщик нагрузки, который подает большие надежды.

Такой выбор был сделан по следующим причинам:

  • хорошая интеграция с Docker, Docker Swarm, Kubernetes
  • более интуитивная конфигурация и настройка
  • HTTPS от Let’s Encrypt из коробки
  • еще ряд некоторых плюшек из разряда Websocket, HTTP/2, метрики Prometheus
  • интересно попробовать

На стороне Apache

По умолчанию веб-сервер Apache слушает 80-й порт, но в данной ситуации его использует nginx, и для Apache необходимо задать альтернативный порт. Новое значение порта должно совпадать с тем, что задано в конфигурационном файле nginx (в нашем случае это — 8080).

Конфигурационный файл Apache в большинстве случаев находится здесь:

/etc/apache2/

Пример содержимого:

ServerName ServerAlias DocumentRoot /var/www/ … #другие параметры

Редактировать заголовки запроса/ответа позволяет модуль mod_headers, устанавливаемый при сборке Apache по умолчанию.

Так как ранее в конфигурационный файл nginx мы включили заголовок X-Real-IP, необходимо настроить Apache для обработки этого заголовка, чтобы получить реальное значение IP-адреса посетителя. Для этого используется модуль mod_remoteip. В версиях Apache >2.4 этот модуль присутствует по умолчанию, активировать его можно командой:

a2enmod remoteip

Если используется версия Apache ниже 2.4, необходимо установить и активировать модуль mod_rpaf:

apt install libapache2-mod-rpaf a2enmod rpaf

Перезагружаем сервис, чтобы применить изменения:

systemctl reload apache2