Nginx Proxy Manager: установка и первоначальная настройка reverse proxy с HTTPS в Docker

Пошаговая установка Nginx Proxy Manager в Docker: настройка reverse proxy, получение SSL-сертификатов Let's Encrypt и проксирование сервисов с HTTPS. Практическое руководство.
⚠️ Дисклеймер: Материал носит исключительно информационный и образовательный характер. Все описанные действия, программное обеспечение, команды и примеры предназначены для изучения технологий, тестирования собственных систем и решения законных технических задач. Автор не призывает использовать приведённую информацию для нарушения законодательства, получения несанкционированного доступа, обхода установленных ограничений или причинения вреда третьим лицам. Перед применением информации убедитесь, что ваши действия соответствуют законодательству Российской Федерации и правилам используемых сервисов.
Зачем вообще нужен reverse proxy?
Представь ситуацию: у тебя дома на одном сервере крутятся Home Assistant, Grafana, Jellyfin, пара веб-морд для ESP32-проектов и, скажем, Nextcloud. Каждый сервис слушает свой порт: 8123, 3000, 8096, 8080... Запомнить всё это невозможно, а уж объяснять домашним, что «умный дом открывается по адресу http://192.168.1.10:8123» — вообще отдельный квест.
И тут на сцену выходит reverse proxy. Это прослойка, которая принимает все входящие запросы на 80-м и 443-м портах и сама решает, какому сервису их передать. Ты заходишь на ha.home.local, а proxy за кулисами перенаправляет трафик на 192.168.1.10:8123. Красиво, правда?
Классическое решение — настроить Nginx вручную, прописав конфиги для каждого хоста. Но когда сервисов становится больше десяти, редактировать текстовые файлы и перезагружать демон после каждого изменения надоедает. Особенно если ты, как и я, любишь экспериментировать и добавлять новые сервисы чуть ли не каждую неделю.
Nginx Proxy Manager (далее — NPM) решает эту проблему элегантно: это веб-интерфейс поверх Nginx, который позволяет управлять прокси-хостами, SSL-сертификатами и правилами доступа буквально в пару кликов. При этом вся мощь оригинального Nginx остаётся под капотом.
В этой статье я покажу, как развернуть NPM в Docker, получить бесплатный SSL-сертификат Let's Encrypt и настроить проксирование на несколько сервисов. Поехали!
Что нам понадобится
Для установки NPM нам нужен любой хост с Docker. Это может быть:
- Raspberry Pi 4 или 5 (отлично тянет)
- Orange Pi или другой одноплатник
- Старый ПК или ноутбук с Linux
- VPS-сервер, если хочешь публиковать сервисы наружу
Я буду показывать на примере Debian/Ubuntu, но команды практически универсальны. Также нам понадобится доменное имя (или хотя бы локальный DNS), потому что Let's Encrypt не выдаёт сертификаты для IP-адресов и локальных имён вроде home.local. Если у тебя нет своего домена — не беда, для тестов подойдёт любой бесплатный сервис вроде DuckDNS.
Важный момент: NPM должен иметь доступ к портам 80 и 443. Убедись, что они не заняты другими сервисами. Если у тебя уже крутится какой-то веб-сервер — его придётся остановить или перевесить на другие порты.
Установка Docker и Docker Compose
Если Docker ещё не установлен, ставим. На Debian/Ubuntu это делается так:
# Обновляем индекс пакетов
sudo apt update
# Устанавливаем зависимости для добавления репозитория
sudo apt install -y ca-certificates curl gnupg
# Добавляем официальный GPG-ключ Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Добавляем репозиторий Docker
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Устанавливаем Docker Engine и плагин Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Для Raspberry Pi и других ARM-устройств команды будут те же, только вместо ubuntu в URL нужно подставить debian (если у тебя Armbian или Raspberry Pi OS). Архитектура подставится автоматически через dpkg --print-architecture.
Проверяем, что всё работает:
sudo docker --version
sudo docker compose version
Если хочешь запускать Docker без sudo — добавь своего пользователя в группу docker:
sudo usermod -aG docker $USER
После этого нужно выйти из сессии и зайти заново (или выполнить newgrp docker).
Разворачиваем Nginx Proxy Manager
Теперь самое интересное. Создадим директорию для проекта и файл docker-compose.yml:
mkdir -p ~/nginx-proxy-manager
cd ~/nginx-proxy-manager
nano docker-compose.yml
Вставляем следующее содержимое:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: always
ports:
# HTTP-порт для редиректов и проксирования
- '80:80'
# HTTPS-порт
- '443:443'
# Порт веб-интерфейса администрирования
- '81:81'
environment:
# Эти переменные задают пароль для шифрования данных в БД
DB_MYSQL_HOST: 'db'
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: 'npm'
DB_MYSQL_PASSWORD: 'npm_pass_2026'
DB_MYSQL_NAME: 'npm'
volumes:
# Здесь NPM хранит конфиги прокси-хостов
- ./dаta:/data
# Сюда складываются SSL-сертификаты
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'mariadb:10.11'
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'root_pass_2026'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm_pass_2026'
volumes:
- ./mysql:/var/lib/mysql
Небольшое пояснение по структуре. Мы поднимаем два контейнера: сам NPM и MariaDB для хранения конфигурации. NPM умеет работать и с SQLite, но с MariaDB надёжнее — особенно если планируется много хостов и правил.
Обрати внимание на порт 81 — это веб-интерфейс администратора. Я специально не выношу его наружу через reverse proxy, потому что админка NPM не должна быть доступна из интернета. Если тебе нужно управлять NPM удалённо — используй VPN или SSH-туннель.
Запускаем:
docker compose up -d
Первая загрузка может занять пару минут, так как Docker будет скачивать образы. Проверяем статус:
docker compose ps
Оба контейнера должны быть в статусе Up. Если что-то пошло не так — смотрим логи:
docker compose logs app
Первоначальная настройка
Открываем браузер и заходим на http://IP_твоего_сервера:81. Ты увидишь страницу входа. Дефолтные учётные данные такие:
- Email:
admin@example.com - Пароль:
changeme
Сразу после первого входа NPM попросит сменить email и пароль. Обязательно сделай это — оставлять дефолтные креды на сервисе, который управляет всем твоим трафиком, — плохая идея.
После смены пароля попадёшь в дашборд. Здесь видно общую статистику: количество прокси-хостов, редиректов, сертификатов и доступных обновлений.
Перед тем как создавать первые хосты, давай настроим доступ к админке. Зайди в Settings → Access Lists и создай список доступа, в который добавишь свой IP-адрес. Это позволит ограничить доступ к админ-панели только с определённых адресов. Полезно, если порт 81 случайно окажется доступен извне.
Настройка DNS
Прежде чем создавать прокси-хосты, нужно, чтобы доменные имена указывали на наш сервер. Есть два сценария:
- Внешний доступ — у тебя есть домен, и ты хочешь публиковать сервисы в интернет. Тогда создай A-записи вида
service.example.com, указывающие на публичный IP сервера. - Локальный доступ — всё крутится внутри домашней сети. Тогда можно использовать локальный DNS (например, Pi-hole или AdGuard Home) или просто прописать записи в
/etc/hostsна клиентских машинах.
Для тестов и локального использования я рекомендую второй вариант. Пропиши в файле /etc/hosts на компьютере, с которого будешь заходить:
192.168.1.100 ha.home.lan
192.168.1.100 grafana.home.lan
192.168.1.100 npm.home.lan
Замени 192.168.1.100 на IP своего сервера.
Получаем SSL-сертификат Let's Encrypt
Теперь переходим к самому вкусному — бесплатным SSL-сертификатам. В NPM это делается через SSL Certificates → Add SSL Certificate → Let's Encrypt.
Нам предложат ввести:
- Domain names — домен, для которого нужен сертификат (например,
ha.home.lan) - Email — на этот адрес будут приходить уведомления о продлении
- Галочку Use a DNS Challenge — обычно не нужна, если домен уже резолвится на наш сервер
Важный момент: перед получением сертификата убедись, что домен реально резолвится в IP нашего сервера. Let's Encrypt проверяет владение доменом через HTTP-запрос на 80-й порт, и если запрос не дойдёт до NPM — сертификат не выдадут.
Типичная ошибка новичков: они пытаются получить сертификат для локального IP или для домена, который ещё не прописан в DNS. Let's Encrypt такие запросы отклоняет. Если тестируешь локально — используй реальный домен, который ты контролируешь, или сервисы вроде DuckDNS.
После успешного получения сертификат появится в списке. Срок его жизни — 90 дней, но NPM автоматически продлевает сертификаты, так что об этом можно забыть.
Создаём первый прокси-хост
Теперь самое интересное — проксирование. Допустим, у нас на сервере крутится Home Assistant на порту 8123. Хотим, чтобы он был доступен по адресу https://ha.home.lan.
Идём в Hosts → Proxy Hosts → Add Proxy Host. Заполняем:
- Domain Names:
ha.home.lan - Scheme:
http - Forward Hostname / IP:
192.168.1.100(илиhost.docker.internal, если сервис крутится на хосте) - Forward Port:
8123 - Block Common Exploits: включаем (защита от типичных атак)
- Websockets Support: включаем (Home Assistant использует WebSocket для дашборда)
Во вкладке SSL выбираем наш сертификат и включаем:
- Force SSL — принудительный редирект с HTTP на HTTPS
- HTTP/2 Support — ускоряет загрузку
Сохраняем. Через пару секунд NPM перечитает конфиг, и https://ha.home.lan заработает. Проверяем в браузере — должен открыться Home Assistant с валидным SSL-сертификатом.
Добавляем ещё сервисы
По аналогии добавляем другие сервисы. Например, Grafana на порту 3000:
- Domain Names:
grafana.home.lan - Forward Hostname / IP:
192.168.1.100 - Forward Port:
3000
И Jellyfin на 8096:
- Domain Names:
jellyfin.home.lan - Forward Hostname / IP:
192.168.1.100 - Forward Port:
8096
Обрати внимание: если сервисы крутятся в Docker на том же хосте, что и NPM, можно использовать имя контейнера вместо IP. Например, если Home Assistant запущен в контейнере с именем homeassistant, то в поле Forward Hostname можно написать homeassistant — Docker DNS сам разрешит это имя в IP контейнера. Но для этого NPM и целевой контейнер должны быть в одной Docker-сети.
Расширенные настройки: кастомные конфиги
Иногда стандартных настроек не хватает. Например, нужно добавить кастомные заголовки или изменить лимиты на размер тела запроса. В NPM для этого есть Advanced вкладка при создании/редактировании прокси-хоста.
Туда можно вписать любые директивы Nginx. Например, для Nextcloud часто нужно увеличить лимит на загрузку файлов:
client_max_body_size 10G;
Или добавить заголовки безопасности:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
Но будь осторожен: NPM не проверяет синтаксис введённого конфига. Если ошибёшься — Nginx может не запуститься, и все прокси-хосты перестанут работать. В таком случае зайди в контейнер и исправь конфиг вручную:
# Заходим в контейнер NPM
docker exec -it nginx-proxy-manager-app-1 bash
# Смотрим конфиги прокси-хостов
ls /data/nginx/proxy_host/
# Редактируем проблемный конфиг
nano /data/nginx/proxy_host/1.conf
# Перезапускаем Nginx внутри контейнера
nginx -s reload
Настройка доступа и авторизации
NPM умеет ограничивать доступ к прокси-хостам по IP-адресам и требовать базовую HTTP-авторизацию. Это удобно, если нужно скрыть сервис от посторонних, но не хочется настраивать авторизацию в самом приложении.
Создаём список доступа: Access Lists → Add Access List. Задаём имя и добавляем правила:
- Access: список разрешённых IP (можно указать
192.168.1.0/24для всей локальной подсети) - Satisfy Any: если включено, достаточно выполнения любого правила (IP ИЛИ логин/пароль)
- Authorization: включаем и добавляем пользователей с логинами и паролями
После создания списка его можно привязать к прокси-хосту во вкладке Access List.
Редиректы и 404-хосты
Помимо проксирования, NPM умеет делать простые HTTP-редиректы. Например, можно настроить переадресацию с http://home.lan на https://ha.home.lan. Это делается в Hosts → Redirection Hosts.
Ещё одна полезная фишка — Custom 404 Host. Если кто-то зайдёт на IP сервера без указания домена, NPM покажет страницу по умолчанию. Можно создать свой хостовый 404-хост, который будет обрабатывать все запросы, не совпавшие ни с одним прокси-хостом. Это удобно, чтобы не светить содержимое сервера случайным посетителям.
Типичные ошибки и как их избежать
За годы использования NPM я наступил на множество граблей. Вот самые распространённые:
1. Конфликт портов
Если на хосте уже запущен веб-сервер (Apache, Nginx или даже Home Assistant в standalone-режиме), порты 80 и 443 будут заняты. Docker-контейнер NPM не сможет их захватить.
Решение: останови существующий веб-сервер или переведи его на другие порты. Home Assistant, кстати, часто ставят именно на 8123, чтобы не конфликтовать.
2. Сервисы в Docker не видят друг друга
Если NPM и целевой сервис запущены в разных Docker-сетях, они не смогут общаться по именам контейнеров. Придётся указывать IP-адрес хоста или использовать host.docker.internal.
Решение: создай общую Docker-сеть и подключи к ней оба контейнера:
docker network create npm_network
# При запуске контейнеров добавляем --network npm_network
# Или в docker-compose.yml указываем:
# networks:
# default:
# external:
# name: npm_network
3. Let's Encrypt не выдаёт сертификат
Самая частая причина — домен не резолвится в публичный IP сервера. Проверь:
nslookup ha.home.lan
Если домен указывает на локальный IP (192.168.x.x), Let's Encrypt не сможет подтвердить владение. Для локальных сервисов используй самоподписанные сертификаты или внутренний CA.
4. WebSocket не работает
Некоторые приложения (Home Assistant, Grafana, Jellyfin) активно используют WebSocket. Если забыть включить Websockets Support в настройках прокси-хоста, дашборды будут работать с перебоями.
5. SSL-сертификат не обновляется
NPM автоматически продлевает сертификаты, но для этого контейнер должен быть запущен и иметь доступ к порту 80. Если ты надолго выключал сервер — проверь статус сертификатов в SSL Certificates.
Проверка результата
После настройки нескольких прокси-хостов давай убедимся, что всё работает как надо.
Проверка SSL-сертификата
Зайди на https://ha.home.lan и посмотри на замок в адресной строке. Сертификат должен быть валидным, без предупреждений. Можно также проверить через openssl:
echo | openssl s_client -connect ha.home.lan:443 -servername ha.home.lan 2>/dev/null | openssl x509 -noout -dates
Ты увидишь даты начала и окончания действия сертификата.
Проверка редиректа
Если включён Force SSL, попробуй зайти на http://ha.home.lan. Браузер должен автоматически перенаправить тебя на HTTPS-версию.
Проверка проксирования
Открой дашборд Home Assistant, Grafana или другого сервиса через доменное имя. Убедись, что всё загружается корректно, дашборды обновляются в реальном времени (это значит, что WebSocket работает).
Проверка заголовков
Посмотрим, какие заголовки отдаёт наш прокси:
curl -I https://ha.home.lan
Ты должен увидеть HTTP/2 200 и заголовки, которые добавляет NPM.
Бэкап и восстановление
Раз уж мы подняли такой важный сервис, давай сразу настроим бэкап. Всё нужное хранится в директориях data и letsencrypt, которые мы смонтировали в тома. Достаточно скопировать их на внешний носитель:
# Создаём архив с данными NPM
tar -czf npm-backup-$(date +%Y%m%d).tar.gz data letsencrypt mysql
# Копируем на внешний диск или в облако
cp npm-backup-*.tar.gz /mnt/backup/
Для восстановления на новом сервере достаточно развернуть docker-compose.yml, остановить контейнеры, распаковать архив в ту же директорию и запустить снова:
docker compose down
tar -xzf npm-backup-20260115.tar.gz
docker compose up -d
Все прокси-хосты, сертификаты и настройки будут на месте.
Что дальше?
NPM — это только вершина айсберга. Теперь, когда у тебя есть удобный reverse proxy, можно задуматься о более серьёзных вещах:
- Мониторинг — связка Grafana + InfluxDB отлично дополнит картину и покажет, что происходит в твоей сети
- Безопасность — если публикуешь сервисы в интернет, обязательно настрой фаервол и подумай о VPN для доступа к админке
- Автоматизация — NPM отлично дружит с Home Assistant, так что можно автоматизировать добавление новых хостов
Если ты используешь одноплатник — загляни в статью про продление жизни SD-карты, потому что Docker на флешку — это серьёзная нагрузка. А для тех, кто хочет управлять контейнерами визуально, рекомендую Portainer.
Заключение
Nginx Proxy Manager — это тот случай, когда сложная технология становится доступной каждому. Никаких ручных конфигов, никакого редактирования файлов через SSH — только красивый веб-интерфейс и пара кликов. При этом под капотом остаётся полноценный Nginx со всеми его возможностями.
Мы разобрали установку NPM в Docker, первичную настройку, получение SSL-сертификатов Let's Encrypt и проксирование нескольких сервисов. Теперь у тебя есть единая точка входа для всех твоих приложений — с автоматическим HTTPS и нормальными доменными именами вместо безликих IP:порт.
А если захочешь копнуть глубже — NPM поддерживает кастомные конфиги Nginx, списки доступа, редиректы и даже балансировку нагрузки. Так что экспериментируй, и пусть твои сервисы всегда будут доступны по красивым адресам.
Понравилась статья?
Поставьте лайк и сохраните полезный материал в закладки.
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Nginx Proxy Manager: красивый reverse proxy с веб-интерфейсом для вашего умного дома
VLESS как туннель между вашими проектами: теория и настройка
WireGuard VPN на одноплатнике: ваш безопасный портал домой
Как проверить IP на блокировку в ТСПУ: рабочий Python-скрипт для диагностики
Как работают ТСПУ Роскомнадзора? Разбираемся вместе
Portainer: Визуальное управление Docker-контейнерами для вашего домашнего сервера