
Nginx Proxy Manager: настройка reverse proxy и HTTPS
Разворачиваем Nginx Proxy Manager в Docker, закрываем административный порт, направляем домен на приложение и выпускаем сертификат без конфликта портов.
Содержание
Nginx Proxy Manager — графическая оболочка над Nginx для настройки reverse proxy. Reverse proxy принимает запрос по публичному домену, завершает HTTPS-соединение и передаёт запрос внутреннему приложению. В панели можно создать такой маршрут без ручного редактирования каждого server-блока Nginx.
Инструмент удобен для домашнего сервера и небольшого VPS с несколькими приложениями, но требует понятной схемы сети. Порты 80 и 443 должен занимать один внешний proxy. Административный порт 81 лучше не открывать в интернет.
Как будет проходить запрос
Представим два контейнера: приложение notes слушает порт 3000, а Nginx Proxy Manager находится с ним в общей сети Docker. DNS-запись notes.example.com указывает на VPS. Посетитель соединяется с портом 443, proxy выбирает правило для домена и обращается к notes:3000 внутри Docker.
Имя notes в этой схеме — имя сервиса Compose. Оно разрешается встроенным DNS Docker только внутри общей сети. Порт 3000 не нужно публиковать как 0.0.0.0:3000, если к приложению обращается лишь proxy.
Если нужна ручная конфигурация без панели, используйте обычный reverse proxy Nginx. Nginx Proxy Manager не добавляет новый сетевой принцип, а управляет тем же маршрутом через интерфейс.
Освободите порты 80 и 443
До установки узнайте, какие процессы уже принимают веб-соединения. Команда выполняется на VPS и ничего не меняет:
sudo ss -lntp '( sport = :80 or sport = :443 or sport = :81 )'
Пустой вывод означает, что эти порты свободны. Если виден nginx, apache2, Caddy или другой контейнер, сначала разберитесь, какие сайты через него работают. Нельзя просто остановить службу на рабочем сервере: это отключит все обслуживаемые ею домены.
Выберите миграцию в отдельное окно работ, сохраните действующие конфигурации и подготовьте возврат. Более простой вариант — оставить системный Nginx и не устанавливать второй proxy. Запуск Nginx Proxy Manager оправдан, когда вы осознанно передаёте ему роль внешнего шлюза.
Проверьте также, что Docker Engine и Compose работают. Базовая установка описана в руководстве по Docker на Ubuntu.
Создайте отдельную сеть proxy
Общая Docker-сеть позволит подключать приложения из разных Compose-проектов. Создайте её один раз на VPS:
docker network create proxy
docker network inspect proxy --format '{{.Name}}'
Первая команда изменяет Docker и создаёт сеть proxy. Вторая должна вывести proxy. Если Docker сообщает, что сеть уже существует, сначала изучите её через docker network inspect proxy: не удаляйте сеть, к которой подключены работающие контейнеры.
Для отмены пустую неиспользуемую сеть можно удалить командой docker network rm proxy. Docker откажется удалять её, пока к ней подключены контейнеры.
Запустите Nginx Proxy Manager
Создайте каталог ~/services/nginx-proxy-manager, перейдите в него и сохраните следующий compose.yaml:
services:
proxy:
image: jc21/nginx-proxy-manager:2.15.1
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy
networks:
proxy:
external: true
Образ jc21/nginx-proxy-manager — официальный образ проекта. В примере закреплён опубликованный тег 2.15.1, чтобы повторный запуск не скачал неожиданно другую версию. Перед новой установкой проверьте список выпусков и выберите актуальный поддерживаемый тег; обновляйте его планово после чтения примечаний.
Порты 80 и 443 опубликованы наружу, а панель 81 привязана к 127.0.0.1. Каталоги data и letsencrypt лежат рядом с Compose-файлом: первый хранит конфигурацию панели, второй — сертификаты и связанные данные. Оба каталога нужны в резервной копии.
Проверьте и запустите проект:
cd ~/services/nginx-proxy-manager
docker compose config --quiet
docker compose up -d
docker compose ps
docker compose logs --tail 80 proxy
Сначала config --quiet проверяет YAML. up -d создаёт контейнер, а две следующие команды показывают его состояние и последние сообщения. Успех — состояние running, локальный ответ порта 81 и отсутствие повторяющихся аварийных перезапусков.
Ошибка address already in use означает конфликт порта. Вернитесь к ss, найдите владельца порта и восстановите план миграции; не меняйте порты 80/443 на случайные, если домен должен открываться обычным HTTPS.
Войдите в панель без публичного порта
На своём компьютере создайте SSH-туннель. Команда не меняет настройки VPS: она занимает порт 8081 только на время работающего SSH-сеанса и завершается сочетанием Ctrl+C:
ssh -N -L 8081:127.0.0.1:81 admin@SERVER_IP
Замените имя пользователя и адрес сервера. Затем откройте http://127.0.0.1:8081. Локальный порт 8081 выбран, чтобы не требовать привилегий на компьютере; туннель передаёт его к порту 81 на VPS.
Актуальные версии Nginx Proxy Manager проводят начальную настройку через мастер. Создайте отдельную учётную запись администратора с уникальным длинным паролем. Не ориентируйтесь на старые статьи с опубликованными логином и паролем по умолчанию: интерфейс и порядок первого входа менялись.
Подключите приложение к сети proxy
В Compose-файле приложения укажите ту же внешнюю сеть. Само приложение не публикуйте наружу:
services:
notes:
image: registry.example.com/team/notes@sha256:ACTUAL_DIGEST
restart: unless-stopped
expose:
- "3000"
networks:
- proxy
networks:
proxy:
external: true
Замените ссылку на образ реальным проверенным образом. expose документирует внутренний порт, но не открывает его на VPS. После docker compose up -d контейнер notes станет доступен контейнеру proxy по адресу http://notes:3000.
Перед настройкой домена проверьте связь из контейнера proxy. Не все образы содержат curl, поэтому надёжнее временно запустить диагностический контейнер в той же сети:
docker run --rm --network proxy curlimages/curl:latest \
--fail --show-error --head http://notes:3000/
Команда скачивает диагностический образ при его отсутствии, отправляет запрос и удаляет временный контейнер. Ожидается HTTP-заголовок приложения. Если имя не находится, проверьте подключение обоих контейнеров к сети proxy. Если соединение отклонено, приложение может слушать только 127.0.0.1 внутри своего контейнера — ему нужно слушать внутренний интерфейс контейнера, обычно 0.0.0.0.
Создайте Proxy Host и сертификат
До выпуска сертификата A- или AAAA-запись домена должна указывать на этот VPS. Проверьте это по инструкции диагностики DNS. Порты 80 и 443 должны быть разрешены firewall и перенаправлены на VPS, если сервер находится за роутером.
В панели откройте Hosts → Proxy Hosts → Add Proxy Host и заполните:
- Domain Names:
notes.example.com; - Scheme:
http, если само приложение внутри сети работает без TLS; - Forward Hostname/IP:
notes; - Forward Port:
3000; - Websockets Support: только если приложение действительно использует WebSocket.
На вкладке SSL запросите новый сертификат Let’s Encrypt, примите условия сервиса и включите принудительный HTTPS после успешного выпуска. Адрес электронной почты нужен для уведомлений центра сертификации. Не включайте HSTS при первом тесте: браузер запомнит требование HTTPS, что осложнит возврат при неверной настройке.
Проверьте результат снаружи
С другого устройства отправьте запрос к публичному домену. Команда только читает заголовки ответа и завершится ненулевым кодом при сетевой или HTTP-ошибке:
curl --fail --silent --show-error --head https://notes.example.com/
Успех — корректный сертификат на имя notes.example.com и ожидаемый HTTP-код приложения. Код 502 означает, что proxy не получил нормальный ответ от notes:3000; вернитесь к проверке общей сети. Ошибка сертификата требует отдельно проверить DNS, доступность 80/443 и журнал proxy.
Убедитесь, что порт приложения не появился снаружи и панель не опубликована на всех интерфейсах:
sudo ss -lntp '( sport = :80 or sport = :443 or sport = :81 or sport = :3000 )'
Порты 80 и 443 должны слушать внешние интерфейсы. Для 81 ожидается только 127.0.0.1; 3000 на хосте не должен слушаться вовсе. Это дополняет, но не заменяет проверку правил firewall.
Как обновлять и возвращать конфигурацию
В резервную копию включите Compose-файл, каталоги data и letsencrypt, а также Compose-файлы подключённых приложений. Перед обновлением прочитайте примечания к выпуску и сохраните текущий идентификатор образа:
docker inspect nginx-proxy-manager --format '{{.Image}}'
docker compose pull
docker compose up -d
После пересоздания повторите проверки панели, одного Proxy Host и сертификата. Для возврата восстановите прежний образ и совместимую копию данных. Простая замена тега назад может не помочь, если новая версия уже изменила внутреннюю базу.
Если решите отказаться от панели, сначала подготовьте обычный Nginx или другой proxy, проверьте его на альтернативном адресе, затем перенесите 80/443 в согласованное окно. Остановка текущего контейнера до готовности замены отключит все домены, которыми он управляет.
Источники
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Можно ли запустить Nginx Proxy Manager рядом с обычным Nginx?
Да, но они не могут одновременно слушать одинаковые адреса и порты 80 и 443. Нужно выбрать один внешний proxy либо разнести службы по адресам или портам и явно спроектировать маршрут.
Почему сертификат Let's Encrypt не выпускается?
Проверьте, что домен уже указывает на этот сервер, входящие порты 80 и 443 доступны, другой процесс их не занимает, а proxy или NAT не мешает проверочному запросу центра сертификации.
Стоит ли публиковать порт панели 81 в интернете?
Для одного VPS безопаснее привязать его к 127.0.0.1 и входить через SSH-туннель. Если панель нужна команде, ограничьте её корпоративной сетью или отдельным защищённым proxy.


