Nginx Proxy Manager в Docker — Полный гайд от установки до Wildcard SSL

Nginx Proxy Manager — HTTPS и проксирование без боли в консоли

Вы купили VPS, подняли на нем несколько сервисов в Docker (например, сайт на Node.js и админку Portainer), и теперь нужно настроить маршрутизацию. Как сделать так, чтобы сайт открывался по mydomain.com, а админка по admin.mydomain.com? И как получить на всё это HTTPS сертификаты, не погружаясь в сложные конфиги Nginx?

Ответ — Nginx Proxy Manager (NPM). Это удобный графический интерфейс для управления прокси-сервером. Но просто “установить” его мало. Часто новички сталкиваются с конфликтами портов, ошибками “502 Bad Gateway” и недоступностью контейнеров.

В этой статье мы разберем правильную установку и решение неочевидных проблем.

Что нам понадобится

  • Linux сервер (Ubuntu 22.04/24.04 или Debian 12).
  • Docker и Docker Compose (установленные).
  • Доменное имя, направленное на IP вашего сервера (A-запись).
  • Открытые порты 80 и 443 в фаерволе.
ООО «РЕГ.РУ»

Мощные VPS для ваших Docker-контейнеров

Идеально подходит для Nginx Proxy Manager, Portainer и Nextcloud. Высокая производительность (NVMe), защита от DDoS и скидка 5% по промокоду.

Промокод: CB2C-C638-E0BF-18D1
от 0.6 ₽/час

Правильная установка — Docker Network

Главная ошибка — запускать NPM и ваши приложения изолированно. Чтобы Nginx Proxy Manager мог перенаправлять трафик на другие контейнеры, они должны находиться в одной Docker-сети.

Создадим внешнюю сеть для наших публичных сервисов:

docker network create public_net

Теперь подготовим файл docker-compose.yml для самого NPM:

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'    # Вход HTTP
      - '443:443'  # Вход HTTPS
      - '81:81'    # Админка
    environment:
      # Опционально: подключение к БД MySQL
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm_password"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - public_net
    depends_on:
      - db

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'npm_root_password'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm_password'
    volumes:
      - ./mysql:/var/lib/mysql
    networks:
      - public_net

networks:
  public_net:
    external: true

Обратите внимание, что мы добавили сервис db (MariaDB). Это рекомендуемый способ запуска для продакшн-окружения, так как встроенная база SQLite может не справляться с большой нагрузкой или повредиться при сбоях питания.

Запускаем: docker-compose up -d.

Решение конфликтов — Порт 80 занят

Если при запуске вы видите ошибку Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use, значит на вашем сервере уже работает веб-сервер (Apache или Nginx).

Как исправить (для Ubuntu):

sudo systemctl stop apache2
sudo systemctl disable apache2
# или если это nginx
sudo systemctl stop nginx
sudo systemctl disable nginx

Порты 80 и 443 должны быть полностью освобождены для нашего Docker-контейнера.

Подключение сервисов через Docker Network

Допустим, вы хотите запустить Gitea и настроить к ней доступ извне. В docker-compose.yml этого сервиса нужно добавить ту же сеть public_net:

version: '3'
services:
  server:
    image: gitea/gitea:latest
    container_name: gitea_server  # Важно задать имя контейнера!
    networks:
      - public_net
    # ports: 
    #   - "3000:3000" <--- УБЕРИТЕ ЭТО! Не открывайте порты наружу.

Теперь в панели управления Nginx Proxy Manager (http://ваш-ip:81):

  1. Domain Name: git.mydomain.com
  2. Scheme: http
  3. Forward Hostname / IP: gitea_server (имя контейнера!)
  4. Forward Port: 3000 (внутренний порт контейнера)

Вам не нужно указывать IP-адреса типа 172.18.0.x. Nginx найдет сервис по его имени gitea_server, так как они находятся в одной сети public_net.

Wildcard SSL — Один сертификат для всех поддоменов

Вместо выпуска отдельных сертификатов для каждого поддомена (blog.site.ru, shop.site.ru), удобнее использовать Wildcard сертификат (*.site.ru).

NPM поддерживает автоматическое получение таких сертификатов через DNS Challenge (подтверждение владения доменом через API DNS-провайдера).

  1. Зайдите в SSL Certificates -> Add SSL Certificate.
  2. Введите домен: *.site.ru (звездочка обязательна).
  3. Включите опцию Use a DNS Challenge.
  4. Выберите вашего DNS-провайдера (Cloudflare, Reg.ru, DigitalOcean и др.).
  5. Вставьте API Token от провайдера в поле конфигурации.

Теперь вы можете создавать множество поддоменов, и все они будут автоматически защищены одним сертификатом.

Заключение

Nginx Proxy Manager — мощный инструмент для управления веб-трафиком. Используя Docker Networks и Wildcard SSL, вы создаете безопасную и масштабируемую инфраструктуру, где сервисы изолированы, а доступ к ним строго контролируется. Больше никаких открытых портов наружу и ручной правки конфигов.