7.8 KiB
Веб-сервер Nginx с SSL-сертификатами Let's Encrypt в контейнерах Docker
Для удобного переноса сайтов или веб-приложений между серверами, а также для упрощения обновления и обслуживания веб-сервера nginx, удобно держать его в контейнере Docker. В данной инструкции рассмотрено развертывание веб-сервера Nginx с SSL-сертификатами Let's Encrypt в контейнерах Docker. В качестве примера используется контейнер Portainer -- отличный инструмент для управления Docker-контейнерами через веб-интерфейс.
Соглашения: пусть наш пользователь от имени которого мы работаем -- web
. Таким образом, домашний каталог -- /home/web
.
Каталог для хранения данных Docker-контейнеров (место куда монтируют тома контейнера) -- /home/web/docker-data
.
И так, для начала создадим каталог для хранения данных Portainer (можно опустить если вам не нужен Portainer):
mkdir -p /home/web/docker-data/portainer
Nginx в контейнере Docker
Теперь создадим каталог для хранения конфигурационных файлов Nginx. Сам Nginx будет сидеть в контейнере, но
конфигурационные файлы, которые он будет использовать, находятся на хосте в каталоге /home/web/docker-data/nginx/conf.d
:
mkdir -p /home/web/docker-data/nginx/conf.d
Теперь создадим файл конфигурации Nginx, который будет использоваться для проксирования запросов к контейнеру Portainer:
nano /home/web/docker-data/nginx/conf.d/portainer.conf
Вставьте в файл следующее содержимое:
server {
listen 80;
server_name portainer.you.domain.name;
location / {
proxy_pass http://portainer:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Что происходит в этом файле конфигурации:
listen 80;
-- слушаем порт 80 (обычный HTTP-трафик);server_name portainer.you.domain.name;
-- имя хоста, по которому будет доступен Portainer (заменитеyou.domain.name
на ваш домен);proxy_pass http://portainer:9000;
-- проксируем запросы в контейнер Portainer, который будет доступен по хосту (имени контейнераportainer
) и порту 9000;proxy_set_header Host $host;
-- передаем заголовокHost
в запросе;proxy_set_header X-Real-IP $remote_addr;
-- передаем заголовокX-Real-IP
в запросе;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-- передаем заголовокX-Forwarded-For
в запросе;
Сохраните файл и выйдите из редактора (Ctrl + X
, затем Y
для подтверждения).
Теперь создадим файл docker-compose.yml
для развертывания контейнеров Nginx и Portainer:
nano /home/web/docker-data/docker-compose.yml
Вставьте в файл следующее содержимое:
version: '3'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
# Гасим порт 9000, чтобы он не светил на хост, а был доступен только во внутри-контейнерной сети
# ports:
# - "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/web/docker-data/portainer:/data
restart: always
networks:
- web
# Можно закомментировать строку выше и раскомментировать строки ниже если зачем-то нужен закрепленный IP-адрес
# web:
# ipv4_address: 172.20.0.10
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- /home/web/docker-data/nginx/conf.d:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt
restart: always
networks:
- web
networks:
web:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24 # Подсеть для пользовательской сети
Что у нас настроено в этом docker-compose.yml
:
portainer
(у вас его может и не быть, или быть какой-то другой сервис, который вы будете производить):image: portainer/portainer-ce:latest
-- используем образ Portainer Community Edition;container_name: portainer
-- имя контейнераportainer
;volumes: ...
-- монтируем файлы или тома изнутри контейнера Portainer на хост. В данном случае монтируем: сокет -- чтобы изнутри контейнера Portainer можно было управлять Docker, в котором сам же и работает (вот так хитро) и каталог/home/web/docker-data/portainer
-- чтобы сохранять данные Portainer между перезапусками;restart: always
-- автоматически перезапускаем контейнер при его остановке;networks: ...
-- подключаем контейнер к пользовательской (внутри-контейнерной) сетиweb
.
nginx
:image: nginx:latest
-- используем образ Nginx;container_name: nginx
-- имя контейнераnginx
;ports: ...
-- пробрасываем порты 80 и 443 на хост;volumes: ...
-- монтируем каталог с конфигурационными файлами Nginx и каталог с SSL-сертификатами Let's Encrypt;restart: always
-- автоматически перезапускаем контейнер при его остановке;networks: ...
-- подключаем контейнер к пользовательской (внутри-контейнерной) сетиweb
.
networks: ...
:web
:driver: bridge
-- используем драйвер сетиbridge
(по умолчанию);ipam: ...
-- настраиваем IP-адреса для контейнеров внутри сетиweb
. В данном случае используем подсеть
Сохраняем файл docker-compose.yml
и выходим из редактора (Ctrl + X
, затем Y
для подтверждения).
Теперь развернем контейнеры Nginx и Portainer:
cd /home/web/docker-data
docker-compose up -d
После того как контейнеры запустятся, можно зайти в веб-интерфейс Portainer по адресу http://portainer.you.domain.name
.