На одном сервере с docker-контейнерами может размещаться несколько веб-приложений, которые необходимо публиковать по http и https. Самый оптимальный способ это сделать в среде Docker — использовать отдельный контейнер с http-прокси, который будет переводить веб-запросы на нужные контейнеры, ориентируясь по доменным именам.
Рассмотрим пример файла docker-compose для проксирования запросов на другие контейнеры и возможностью получения сертификатов от Let’s Encrypt.
Подготовка системы
Пример файла docker-compose.yml
Описание compose-файла
Запуск контейнера
Пример настройки виртуального домена
Настройка сети в docker-compose для работы с entrypoint
Получение сертификата от Let’s Encrypt
Дополнительные материалы
Подготовка
Выполним предварительные действия. Предполагается, что мы будем хранить наш файл docker-compose в каталоге /opt/nginx .
Создаем каталог:
mkdir /opt/nginx
Перейдем в него:
cd /opt/nginx
Создаем файл docker-compose.yml:
vi docker-compose.yml
Мы готовы к написанию сценария.
Docker-compose
Пример нашего файла compose:
- services:
- nginx-entrypoint:
- image: nginx
- hostname: nginx-entrypoint
- container_name: nginx-entrypoint
- restart: unless-stopped
- environment:
- TZ: «Europe/Moscow»
- ports:
- — 80:80
- — 443:443
- volumes:
- — ./conf/conf.d:/etc/nginx/conf.d
- — ./conf/ssl:/etc/nginx/ssl
- — ./well-known:/usr/share/nginx/html
- — /opt/letsencrypt:/etc/letsencrypt
- networks:
- — dnet
- networks:
- dnet:
- name: dnet
- driver: bridge
Описание сценария
Кратко опишем, что выполнит наш сценарий. Подробнее про работу с docker-compose можно прочитать в инструкции Шпаргалка по работе с docker-compose .
1 — 19 | Поднимаем контейнер с nginx прокси. |
13 | Дополнительные конфигурационные файлы, которые будут подгружаться к основному. В них мы будем хранить настройки для виртуальных доменов. |
14 | Хранение самоподписанных или платных сертификатов. |
15 | Каталог обмена контентом, который нужен для валидации домена. Используется при получении бесплатных сертификатов от Let’s Encrypt. |
16 | Бесплатные сертификаты, полученные от Let’s Encrypt. |
20 — 23 | Общая сеть. Ее мы будем добавлять к другим службам других контейнеров для обеспечения сетевой доступности между данным контейнерами и нашим entrypoint. |
Запуск
Продолжая находиться в каталоге с файлом docker-compose, выполним команду:
docker-compose up -d
При первом запуске система загрузит образ с nginx и запустит контейнер. Посмотреть его состояние можно командой:
docker-compose ps
Пример конфигурации виртуального домена
Рассмотрим простой пример создания конфигурационного файла для проксирования http запросов.
Убедимся, что мы находимся в рабочем каталоге:
cd /opt/nginx
Для удобства создадим переменную с именем домена:
DOMAIN=test.domain.ru
Создаем конфигурационный файл:
vi conf/conf.d/${DOMAIN}.conf
* обязательно, чтобы название файла заканчивалось на .conf .
server {
listen 80;
server_name test.domain.ru;
location / {
proxy_pass http://my_site_container;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
* nginx с данной конфигурацией будет переводить запросы на контейнер my_site_container для запросов к сайту test.domain.ru .
Чтобы наш конфигурационный файл работал, контейнер nginx-entrypoint должен видеть сервис my_site_container (из нашего примера). Создадим его для теста:
docker run —rm -d —name my_site_container —network dnet nginx
* наш контейнер будет с именем my_site_container , работать в сети dnet .
Теперь можно применить конфигурацию nginx, но для начала, проверим корректность конфига:
docker exec nginx-entrypoint nginx -t
Если видим:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
… перечитываем конфигурацию:
docker exec nginx-entrypoint nginx -s reload
Можно проверять — при обращении к нашему домену в браузере мы должны получить страницу приветствия nginx:
После завершения проверки можно удалить тестовый контейнер:
docker rm -f my_site_container
И уже работать со своими образами.
Настройка других docker-compose
Также рассмотрим небольшой пример куска сценария для других файлов docker-compose, где будут описаны сервисы, которые должны взаимодействовать с нашим nginx-entrypoint. Последний работает в созданной сети dnet — это значит, что для сервиса нужно указать такую настройку:
services:
service_name:
…
networks:
— default
— dnet
…
networks:
…
dnet:
name: dnet
external: true
* итого, чтобы все работало, среди перечня сетей должна быть перечислена та, в которой находится nginx-entrypoint (в нашем примере это dnet ).
Чтобы данные настройки применились, запускаем команду:
docker-compose up -d
Будут перезапущены контейнеры, которых коснулись изменения.
Получение сертификата (настройка HTTPS)
Ну и напоследок, рассмотрим процесс получения сертификата от Let’s Encrypt. Подробнее процесс описан в инструкции Получение бесплатного SSL сертификата Let’s Encrypt .
Откроем наш конфигурационный файл для настройки виртуального домена:
vi /opt/nginx/conf/conf.d/${DOMAIN}.conf
Внесем изменения (выделены желтым):
server {
listen 80;
server_name test.domain.ru;
location ~ /.well-known {
root /usr/share/nginx/html;
allow all;
}
location / {
proxy_pass http://my_site_container;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
* мы добавили инструкцию для веб-сервера, чтобы при запросах на URL /.well-known он выполнял поиск файлов в каталоге /usr/share/nginx/html .
Перезапускаем nginx:
docker exec nginx-entrypoint sh -c «nginx -t && nginx -s reload»
Для получения сертификата в docker мы будем использовать образ certbot/certbot:
docker run -it —rm —name certbot -v «/opt/letsencrypt:/etc/letsencrypt» -v «/opt/nginx/well-known:/usr/share/nginx/html» certbot/certbot certonly —webroot —agree-tos —email postmaster@remontka.com —webroot-path /usr/share/nginx/html/ -d ${DOMAIN}
* в данном примере мы задействуем пути, которые описали выше в сценарии — каталог /opt/letsencrypt , куда будут сохранены полученные сертификаты и /opt/nginx/well-known для размещения временных файлов, необходимых при проверке домена.
** Мы получим сертификат для хоста test.domain.ru . Важно, чтобы данные имена вели на наш сервер с nginx.
Если все пройдет успешно, мы увидим:
…
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/test.domain.ru/fullchain.pem
Key is saved at: /etc/letsencrypt/live/test.domain.ru/privkey.pem
…
Теперь нужно вернуться к конфигурационному файлу для виртуального домена:
vi /opt/nginx/conf/conf.d/${DOMAIN}.conf
И разрешить использование ssl:
- Заменяем значение listen с 80 на 443 ssl .
- Добавляем опции ssl_certificate и ssl_certificate_key в качестве значений который, соответственно, прописываем открытый и закрытый ключи.
- Дописываем блок с listen 80 для настройки автоматического редиректа с http на https.
Все изменения выделены желтым:
server {
listen 443 ssl;
server_name test.domain.ru;
location ~ /.well-known {
root /usr/share/nginx/html;
allow all;
}
ssl_certificate /etc/letsencrypt/live/test.domain.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.domain.ru/privkey.pem;
location / {
proxy_pass http://my_site_container;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name test.domain.ru;
return 301 https://$host$request_uri;
}
Проверяем конфигурацию и перечитываем ее:
docker exec nginx-entrypoint sh -c «nginx -t && nginx -s reload»
Снова открываем в браузере наш сайт — запрос должен быть переброшен на https.
Для продления сертификатов можно использовать команду:
docker run -it —rm —name certbot -v «/opt/letsencrypt:/etc/letsencrypt» -v «/opt/nginx/well-known:/usr/share/nginx/html» certbot/certbot renew
После продления необходимо перечитать конфигурацию nginx:
docker exec nginx-entrypoint nginx -s reload
Также мы можем настроить задание в cron, например:
crontab -e
0 0 * * 1,4 /usr/bin/docker run —rm —name certbot -v «/opt/letsencrypt:/etc/letsencrypt» -v «/opt/nginx/well-known:/usr/share/nginx/html» certbot/certbot renew && /usr/bin/docker exec nginx-entrypoint sh -c «nginx -t && nginx -s reload»
Читайте также
Дополнительные материалы по теме:
1. Установка Docker на Linux .
2. Создание собственного образа Docker .
3. Настройка веб-сервера в Docker (NGINX + PHP + MariaDB) .
4. Настройка локального репозитория для образов Docker и работа с ним .