Nginx Proxy Manager (NPM) — это решение, которое кардинально упрощает управление обратным прокси-сервером и SSL-сертификатами. Если вы устали от ручного редактирования конфигураций nginx и скриптов для обновления Let's Encrypt, этот инструмент, запущенный в Docker, даст вам удобный веб-интерфейс для управления десятками сервисов. В этом руководстве вы получите готовый, проверенный на практике docker-compose.yml, пошаговую настройку автоматического SSL и конкретные примеры интеграции с Home Assistant и Nextcloud — всё, что нужно для быстрого развертывания надежного прокси в production-среде.
Что такое Nginx Proxy Manager и почему он нужен в Docker
Nginx Proxy Manager — это веб-приложение, которое выступает как фронтенд для управления конфигурациями веб-сервера nginx. Его главная ценность — устранение рутинных операций: вместо правки текстовых файлов и запуска certbot вы настраиваете проксирование и SSL через интуитивный графический интерфейс. Запуск в Docker изолирует все зависимости, гарантирует воспроизводимость установки и упрощает обновление до новых версий.
Архитектура NPM: как веб-панель управляет nginx внутри контейнера
Контейнер NPM включает в себя три ключевых компонента: сам веб-сервер nginx (который и обрабатывает трафик), базу данных SQLite (или MariaDB, в зависимости от конфигурации) для хранения настроек и веб-приложение на Node.js, которое предоставляет административный интерфейс. Когда вы создаете или изменяете прокси-хост через веб-панель, приложение генерирует соответствующий конфигурационный файл nginx (в формате .conf) и сигнализирует nginx о необходимости перезагрузить конфигурацию. Этот подход объединяет мощь и производительность nginx с простотой управления через GUI.
NPM vs Traefik vs Caddy: краткое сравнение для Docker-окружения
Выбор reverse-proxy для Docker-окружения зависит от ваших приоритетов. Вот объективное сравнение трех популярных решений на 2026 год:
- Nginx Proxy Manager (NPM): Главное преимущество — наличие полноценного веб-интерфейса. Идеален, когда нужен простой и наглядный контроль над прокси и SSL без погружения в декларативные конфиги (как у Traefik) или Caddyfile. Минус — отсутствие нативной поддержки автоматического обнаружения сервисов через Docker labels (как у Traefik).
- Traefik: Обладает мощной системой автоматического обнаружения сервисов (Docker, Kubernetes) через метки (labels). Конфигурация — декларативная, через те же labels или отдельные файлы. Отличный выбор для динамичных микросервисных сред, но имеет более крутую кривую обучения и менее наглядный интерфейс для ручного управления.
- Caddy: Выделяется простотой конфигурации (Caddyfile) и автоматическим HTTPS «из коробки». Легковесный и простой в настройке для базовых сценариев. Однако для управления множеством сервисов и сложных правил может потребоваться больше ручной работы по сравнению с NPM.
Вывод: Если вам нужен простой GUI для централизованного управления доступом к десяткам внутренних сервисов (домашняя лаборатория, сервер для небольших проектов) с автоматическим SSL, NPM — оптимальный выбор. Для полностью автоматизированного деплоя в оркестрируемых средах (Kubernetes) чаще выбирают Traefik.
Подготовка Docker-хоста и запуск контейнера NPM
Перед началом убедитесь, что на вашем Linux-сервере (Ubuntu 22.04 LTS/Debian 12 или аналогичном) установлены Docker Engine и Docker Compose. Если вам нужно освежить знания по основам Docker, рекомендуем ознакомиться с нашим полным руководством по Docker для DevOps и системных администраторов в 2026 году.
Проверка системы и освобождение портов 80/443
Самая частая ошибка при первом запуске — конфликт портов с другим веб-сервером (например, Apache или уже запущенным nginx). Выполните команды для проверки:
sudo ss -tulpn | grep ':80\|:443'
# Или
sudo netstat -tulpn | grep ':80\|:443'
Если порты заняты, вам необходимо остановить или перенастроить конфликтующий сервис. Например, для остановки Apache: sudo systemctl stop apache2. Для production-среды рекомендуется убедиться, что эти порты открыты в брандмауэре для входящего трафика из интернета.
Готовый docker-compose.yml для Nginx Proxy Manager (2026)
Создайте директорию для проекта (например, /opt/npm) и разместите в ней файл docker-compose.yml следующего содержания. Этот файл использует актуальный на 2026 год образ, настраивает volumes для сохранения данных и корректные сетевые параметры.
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80' # HTTP трафик
- '443:443' # HTTPS трафик
- '81:81' # Админ-панель
environment:
# ОПЦИОНАЛЬНО: Задать свои учетные данные для первого входа
# Если не задать, по умолчанию: admin@example.com / changeme
# DB_SQLITE_FILE: "/data/database.sqlite"
volumes:
- ./data:/data # База данных и конфигурации NPM
- ./letsencrypt:/etc/letsencrypt # SSL-сертификаты Let's Encrypt
networks:
- npm-network
# Рекомендуется использовать отдельную сеть для изоляции
networks:
npm-network:
driver: bridge
Пояснение ключевых параметров:
- volumes: Маппинг директорий
./dataи./letsencryptкритически важен. Он гарантирует, что ваши настройки и SSL-сертификаты не будут потеряны при пересоздании или обновлении контейнера. - networks: Создание отдельной сети
npm-network— хорошая практика. В дальнейшем вы сможете подключать к этой же сети другие контейнеры (например, с веб-приложениями), обеспечивая им прямое взаимодействие с NPM по именам хостов. - ports: Порт 81 для админ-панели рекомендуется в дальнейшем ограничить доступом только с доверенных IP через брандмауэр.
Запуск и проверка работоспособности контейнера
В директории с файлом docker-compose.yml выполните:
sudo docker-compose up -d
Проверьте, что контейнер запущен и работает:
sudo docker-compose ps
# Должен быть статус "Up"
Просмотрите логи на предмет критических ошибок:
sudo docker-compose logs --tail 50 app
Успешный запуск будет сопровождаться строками об инициализации базы данных и запуске nginx. Теперь админ-панель доступна по адресу http://IP_ВАШЕГО_СЕРВЕРА:81.
Первичная настройка через веб-панель и создание прокси-хостов
Вход в админ-панель и изменение стандартного пароля
Перейдите по адресу http://IP_ВАШЕГО_СЕРВЕРА:81. Используйте стандартные учетные данные для первого входа:
- Email:
admin@example.com - Пароль:
changeme
Сразу после входа система предложит вам изменить email и пароль администратора. Это обязательный шаг для обеспечения безопасности.
Создание прокси-хоста: детальный разбор каждой опции формы
Перейдите в Hosts → Proxy Hosts и нажмите Add Proxy Host. Заполните форму:
- Domain Names: Доменное имя, по которому будет доступен сервис (напр.,
app.yourdomain.com). Можно указать несколько через запятую. Для поддоменов используйте звездочку (напр.,*.apps.yourdomain.com). - Scheme: Протокол, по которому NPM будет соединяться с внутренним сервисом. Важно: Если ваш внутренний сервис (например, контейнер с приложением) не использует HTTPS, выбирайте
http. Выборhttpsздесь требуется, только если сервис уже слушает на 443 порту со своим SSL. - Forward Hostname / IP: IP-адрес или имя хоста (в Docker сети) вашего сервиса. Например, если контейнер с приложением запущен в той же сети
npm-networkи названweb-app, укажитеweb-app. Для сервиса на физическом хосте в локальной сети — его локальный IP (например,192.168.1.100). - Forward Port: Порт, на котором слушает ваш внутренний сервис (например,
8080).
Дополнительные опции (вкладка Advanced):
- Cache Assets: Включает кэширование статических ресурсов (CSS, JS, изображения) в nginx. Рекомендуется для веб-приложений.
- Block Common Exploits: Включает базовый набор правил nginx для блокировки распространенных веб-атак. Рекомендуется.
- Websockets Support: Критически важно для сервисов, использующих WebSockets (например, Home Assistant, Node-RED). Обязательно включите этот флаг для них.
После сохранения прокси-хост станет активным. Если доменное имя разрешается на IP вашего сервера, вы сможете получить доступ к своему сервису через указанный домен.
Автоматическое получение и продление SSL-сертификатов Let's Encrypt
Одна из ключевых функций NPM — автоматизация работы с Let's Encrypt. Это избавляет от ручного управления certbot и cron-заданиями.
Подготовка DNS: A-record, CNAME и доступность домена
Перед запросом сертификата убедитесь, что DNS-записи вашего домена корректно настроены и propagated. Для сервера со статическим публичным IP:
- Создайте A-запись (например,
home.yourdomain.com), указывающую на публичный IP вашего сервера.
Для сервера в облаке или с динамическим IP (DDNS):
- Настройте DDNS-клиент на сервере для обновления IP. Создайте CNAME-запись (например,
home.yourdomain.com), указывающую на ваш DDNS-хост (напр.,myhome.ddns.net).
Проверьте запись командой: dig home.yourdomain.com или nslookup home.yourdomain.com.
DNS Challenge vs HTTP Challenge: какой метод выбрать
NPM поддерживает два метода проверки владения доменом от Let's Encrypt:
- HTTP Challenge: Let's Encrypt пытается обратиться к вашему серверу по домену на порт 80 по пути
/.well-known/acme-challenge/.... Требует, чтобы порт 80 был открыт из интернета и направлен на контейнер NPM. Стандартный и самый простой метод для серверов в облаке (VPS). - DNS Challenge: Let's Encrypt проверяет наличие специальной TXT-записи в DNS вашего домена. Ключевое преимущество: не требует открытия портов на сервере. Это единственный рабочий метод для серверов за NAT (домашних), где порт 80 может быть закрыт провайдером, а также для получения wildcard-сертификатов (для всех поддоменов).
Рекомендация: Для домашних серверов или если вы хотите получить wildcard-сертификат (*.yourdomain.com) — используйте DNS Challenge. Для серверов в облаке с открытым портом 80 подойдет HTTP Challenge.
Решение типовых ошибок получения SSL
Если получение сертификата завершается ошибкой, следуйте чек-листу:
- Проверьте логи NPM:
sudo docker-compose logs app | grep -i acmeили смотрите подробные логи в веб-панели (System → Logs). - Проверьте DNS: Убедитесь, что A/CNAME запись разрешается в правильный IP с помощью публичных DNS (
dig @8.8.8.8 home.yourdomain.com). - Для HTTP Challenge: Проверьте, доступен ли порт 80 вашего сервера из интернета:
telnet ваш_публичный_IP 80с внешней машины. - Лимиты Let's Encrypt: Помните об ограничении в 5 неудачных попыток получения сертификата для одного домена в неделю. При частых ошибках используйте staging-окружение (опция в форме запроса SSL) для отладки.
После успешного получения сертификат будет автоматически продлеваться NPM за 30 дней до истечения срока.
Интеграция с популярными сервисами: Home Assistant, Nextcloud и другие
Приведем конкретные примеры конфигурации для типовых случаев.
Home Assistant: настройка прокси с поддержкой WebSockets
Для корректной работы Home Assistant через обратный прокси критически важна поддержка WebSockets.
- Domain Names:
ha.yourdomain.com - Scheme:
http(если HA внутри сети не использует SSL) - Forward Hostname / IP: Локальный IP вашего сервера с HA (напр.,
192.168.1.10) или имя контейнера в общей Docker сети (напр.,homeassistant). - Forward Port:
8123(стандартный порт HA) - Вкладка Advanced: Обязательно включите Websockets Support.
После сохранения и настройки SSL вы получите безопасный внешний доступ к HA.
Nextcloud и другие веб-приложения
Настройка для Nextcloud или аналогичных приложений (WordPress, Gitea) стандартна:
- Domain Names:
cloud.yourdomain.com - Scheme:
http(рекомендуется, если Nextcloud работает внутри сети по HTTP). Если Nextcloud сам настроен на HTTPS, укажитеhttps. - Forward Hostname / IP: IP или имя хоста контейнера/сервера с Nextcloud.
- Forward Port:
8080(или другой порт, на котором слушает приложение).
Важно для Nextcloud: После настройки вам может потребоваться добавить домен в список trusted_domains в конфигурации Nextcloud (config/config.php). Также в NPM можно на вкладке Advanced добавить дополнительные заголовки, если приложение требует их для корректной работы (например, для определения реального IP клиента):
# В поле Custom Nginx Configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Безопасность и настройки для надежной работы в production
Базовая установка NPM требует дополнительных настроек для production-среды.
Ограничение доступа к админ-панели и прокси-хостам
Порт 81 (админка) не должен быть открыт для всего интернета. Настройте брандмауэр. Для ufw на Ubuntu:
sudo ufw allow from 192.168.1.0/24 to any port 81 proto tcp
sudo ufw deny 81/tcp
Это разрешит доступ к панели только из локальной сети 192.168.1.0/24.
Внутри NPM используйте Access Lists (в меню слева). Вы можете создать список с базовой HTTP-аутентификацией и применить его к любому публичному прокси-хосту, добавив дополнительный слой защиты.
Резервное копирование и обновление: сохраняем конфигурацию
Все критически важные данные хранятся в volumes, указанных в docker-compose.yml. Для резервного копирования достаточно архивировать директории ./data и ./letsencrypt.
tar -czf npm-backup-$(date +%Y%m%d).tar.gz ./data ./letsencrypt
План обновления:
- Выполните резервное копирование.
- Остановите контейнер:
sudo docker-compose down. - Загрузите новую версию образа:
sudo docker-compose pull. - Запустите контейнер:
sudo docker-compose up -d.
Для построения отказоустойчивых production-сред на Docker изучите наш гайд Docker в Production: безопасный деплой, мониторинг и логирование.
Диагностика проблем: чек-лист для ошибок 502 и 'Connection refused'
Анализ логов контейнера: где найти причину ошибки
Первым делом проверьте логи NPM. Используйте команду с follow для отслеживания в реальном времени:
sudo docker-compose logs -f --tail 100 app
Ищите сообщения об ошибках в момент обращения к проблемному домену. Ошибки вида connect() failed (111: Connection refused) указывают на проблему связи с внутренним сервисом.
Пошаговый чек-лист для ошибки 502 Bad Gateway
Ошибка 502 означает, что nginx не может установить соединение с внутренним сервисом.
- Проверьте доступность внутреннего сервиса. Зайдите на хост Docker и выполните запрос напрямую:
curl -v http://ВНУТРЕННИЙ_IP:ПОРТ. Убедитесь, что сервис отвечает. - Проверьте настройки прокси-хоста в NPM. Убедитесь, что поля Forward Hostname/IP и Forward Port указаны верно. Для контейнеров в общей сети используйте имя контейнера, а не IP, так как IP может меняться.
- Проверьте сетевую связность. Если сервис находится в другой Docker-сети, убедитесь, что контейнер NPM подключен к ней. Используйте
docker network inspect СЕТЬ_СЕРВИСА, чтобы увидеть список подключенных контейнеров. - Проверьте брандмауэр хоста. Убедитесь, что внутренние правила брандмауэра (iptables, firewalld) не блокируют трафик между контейнерами или с хоста на контейнер.
Для глубокого понимания сетевой модели Docker и диагностики подобных проблем обратитесь к практическому гайду по продвинутому Docker, сетям и оптимизации.