Traefik как обратный прокси-сервер для контейнеров Docker

Конечно же, для полноценной работы веб-проектов такого простого окружения недостаточно, почти сразу же возникнет проблема – как разместить несколько сайтов на одном сервере? Казалось бы, какая же это проблема – просто по тому же принципу развернуть еще несколько контейнеров? Вот только 80 порт уже занят. И сертификаты для https тоже нужны – без них тебя уже браузер на сайт может не пустить. Сегодня попытаемся исправить эти недочеты и запустим в контейнере прокси-сервер Traefik, который к тому же еще и сертификаты на наш домен автоматически подтянет.

Давайте разбираться. Основная задача прокси-сервера при работе с веб-серверами заключается в принятии всех запросов на любой из ваших сайтов “на себя”, обработку этих запросов и направление их на нужный ресурс. Суть в том, что в интернет вы выставляется только прокси-сервер,  он в свою очередь будет принимать все запросы и распределять их по контейнерам. Таким образом у вас может быть хоть 2, хоть 10 контейнеров с сайтами или веб-приложениями, и каждому можно будет обратиться по доменному имени.

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

Почему будем использовать именно Traefik? Он поставляется в виде крошечного образа, обеспечивает, при необходимости, балансировку нагрузки, позволяет обновлять конфигурацию без перезагрузки и автоматически получает сертификаты для всех доменных имен.

Перейдем к практике

В директории нашего проекта, который мы создавали в прошлой заметке, необходимо создать еще одну директорию – traefik

В этой директории необходимо создать два файла – один конфигурационный файл и один json, в котором будут храниться наши сертификаты.

В файле acme.json хранятся файлы сертификатов, поэтому для Traefik обязательно нужно заблокировать этот файл – чтобы только root мог читать или изменять его

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

Генерируем пароль:

Замените traefik-pass на ваш пароль и запомните вывод утилиты. Выглядеть он будет примерно так:

Теперь открываем конфигурационный файл Traefik:

И пишем в него следующее:

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

 

Разберем все по порядку

В предыдущей статье мы рассмотрели часть конфигурации, поэтому сейчас опишу только изменения.

Здесь мы описываем создание сервиса Traefik, образ которого берем напрямую с DockerHub.

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

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

Пробрасываем в контейнер сокет Docker и файлы конфигураций.

Поле labels не хранит переменных окружения, в отличие от environment, но Traefik способен прочитать labels и взять от туда данные, в которых мы указываем поддомен для доступа на панель мониторинга и порт, на котором эта панель должна работать

Задаем контейнеру уникальное имя, чтобы не полагаться на генератор имен Docker Compose

Прилинковываем Traefik к контейнеру с Apache

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

Также указываем сети, с которыми работает Apache – по одной он соединяется с Traefik, по второй с базой данных.

Указываем labels сервиса mariadb (базы данных) для Traefik, чтобы он не пытался связываться с контейнером.

Создаем сети для связи контейнеров.

На этом все. Сохраняем файл docker-compose.yml и собираем проект:

и получаем полностью готовый к работе веб-сервер, с сертификатами Letsencrypt и автоматическим перенаправлением с http на https.