ورود به پنل ثبت‌ نام

نصب Nginx Proxy Manager؛ چند دامنه روی یک سرور با SSL

نصب Nginx Proxy Manager با داکر برای مدیریت چند دامنه روی یک سرور ابری؛ صدور خودکار گواهی SSL رایگان، پشتیبانی WebSocket و دسترسی امن به پنل مدیریت.

تیم ابر سپهر 10 دقیقه مطالعه
نصب Nginx Proxy Manager؛ چند دامنه روی یک سرور با SSL
در این مقاله

وقتی روی یک سرور بیش از یک سرویس اجرا می‌کنید، خیلی زود به یک محدودیت ساده می‌رسید: پورت‌های ۸۰ و ۴۴۳ یکی بیشتر نیستند. n8n روی ۵۶۷۸ است، پنل دیگری روی ۳۰۰۰ و سرویس سومی روی ۲۲۸۳؛ اما کاربر نمی‌خواهد (و نباید) شماره‌ی پورت را در مرورگر تایپ کند و هیچ‌کدام از این پورت‌ها هم گواهی SSL ندارند. نصب Nginx Proxy Manager ساده‌ترین پاسخ به این وضعیت است.

Nginx Proxy Manager یا به‌اختصار NPM، یک رابط گرافیکی روی Nginx است که کار پراکسی معکوس، مدیریت دامنه‌ها و صدور خودکار گواهی رایگان Let's Encrypt را به چند کلیک تبدیل می‌کند. به‌جای نوشتن و نگهداری چند فایل پیکربندی و اجرای دستی Certbot، یک جدول از دامنه‌ها دارید که هرکدام به یک سرویس داخلی اشاره می‌کنند و گواهی‌شان خودکار تمدید می‌شود.

در این راهنما NPM را با داکر روی Ubuntu 24.04/26.04 یا Debian 13 نصب می‌کنیم، پنل مدیریت را به‌شکل امن (نه روی اینترنت) در دسترس می‌گذاریم، اولین دامنه را با SSL راه‌اندازی می‌کنیم و یک سرویس موجود مثل n8n را پشت آن می‌بریم.

پیش‌نیازها

  • یک سرور ابری با دسترسی root و داکر نصب‌شده. اگر داکر ندارید، راهنمای نصب داکر روی اوبونتو را ببینید.
  • یک دامنه که بتوانید رکوردهای DNS آن را ویرایش کنید.
  • پورت‌های ۸۰ و ۴۴۳ آزاد روی سرور. اگر Nginx یا Apache به‌صورت سیستمی نصب است، باید متوقفش کنید؛ دو برنامه نمی‌توانند هم‌زمان یک پورت را بگیرند.
  • حدود ۵۱۲ مگابایت حافظه‌ی آزاد؛ خود NPM سبک است و بار اصلی روی سرویس‌های پشت آن است.

گام ۱: آزاد کردن پورت‌های ۸۰ و ۴۴۳

اول ببینید چه چیزی روی این پورت‌ها گوش می‌دهد:

ss -tlnp | grep -E ':80 |:443 '

اگر خروجی خالی بود، آماده‌اید. اگر nginx یا apache2 دیدید، سرویس سیستمی را متوقف و غیرفعال کنید:

systemctl disable --now nginx

این کار پیکربندی‌های قبلی شما را پاک نمی‌کند، فقط سرویس را از کار می‌اندازد. از این پس Nginx داخل کانتینر NPM نقش وب‌سرور لبه را بازی می‌کند و پیکربندی از طریق پنل انجام می‌شود.

گام ۲: ساخت شبکه‌ی داکر برای سرویس‌ها

پیش از اجرای NPM، یک شبکه‌ی داکر اختصاصی می‌سازیم:

docker network create proxy

دلیلش مهم است: کانتینرهایی که در یک شبکه‌ی داکر مشترک باشند، می‌توانند یکدیگر را با نام کانتینر صدا بزنند. یعنی در پنل به‌جای آی‌پی، می‌نویسید n8n و پورت 5678؛ اگر روزی کانتینر بازسازی شود و آی‌پی داخلی‌اش عوض شود، چیزی خراب نمی‌شود.

گام ۳: اجرای Nginx Proxy Manager

یک پوشه برای پیکربندی می‌سازیم:

mkdir -p /opt/npm && cd /opt/npm
nano docker-compose.yml

با این محتوا:

services:
  app:
    image: 'jc21/nginx-proxy-manager:2.15.1'
    container_name: npm
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '127.0.0.1:81:81'
    environment:
      TZ: 'Asia/Tehran'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - proxy

networks:
  proxy:
    external: true

نکته‌های کلیدی این فایل:

  • 127.0.0.1:81:81 پنل مدیریت را فقط روی خود سرور منتشر می‌کند. پورت ۸۱ رابط مدیریتی NPM است و هیچ دلیلی ندارد که روی اینترنت باز باشد؛ در گام بعد از تونل SSH برای رسیدن به آن استفاده می‌کنیم.
  • دو والیوم ./data و ./letsencrypt تمام دارایی شما هستند: پیکربندی دامنه‌ها، کاربران پنل و گواهی‌های صادرشده. کل بک‌آپ NPM یعنی همین دو پوشه.
  • پین کردن نسخه‌ی ایمیج (به‌جای latest) باعث می‌شود به‌روزرسانی زمانی اتفاق بیفتد که خودتان تصمیم می‌گیرید، نه با یک docker compose pull اتفاقی.

حالا سرویس را بالا بیاورید:

docker compose up -d
docker compose logs -f

اولین اجرا چند ده ثانیه طول می‌کشد چون پایگاه داده‌ی داخلی ساخته می‌شود.

گام ۴: ورود امن به پنل مدیریت

چون پورت ۸۱ روی اینترنت باز نیست، از کامپیوتر خودتان یک تونل SSH بسازید:

ssh -L 8181:127.0.0.1:81 root@SERVER_IP

تا وقتی این نشست باز است، آدرس http://127.0.0.1:8181 روی مرورگر شما به پنل سرور وصل می‌شود. نام کاربری و رمز پیش‌فرض:

Email:    admin@example.com
Password: changeme

بلافاصله پس از اولین ورود، ایمیل و رمز را عوض کنید. اگر روزی تصمیم گرفتید پنل را روی اینترنت منتشر کنید و رمز پیش‌فرض هنوز سرجایش باشد، عملاً کنترل کامل پراکسی و دامنه‌های خود را واگذار کرده‌اید. NPM در همان ورود اول این تغییر را از شما می‌خواهد؛ نادیده‌اش نگیرید.

گام ۵: تنظیم رکوردهای DNS

برای هر سرویسی که می‌خواهید منتشر کنید، یک رکورد A بسازید که به آی‌پی سرور اشاره کند؛ مثلاً n8n.domain.com و chat.domain.com. اگر تعداد سرویس‌ها زیاد است، می‌توانید یک رکورد wildcard (*.domain.com) بسازید و بعد هر سابدامین را فقط در پنل تعریف کنید.

پیش از رفتن به گام بعد، از انتشار رکورد مطمئن شوید:

dig +short n8n.domain.com

اگر خروجی آی‌پی سرور شما نبود، صبر کنید. صدور گواهی Let's Encrypt با روش HTTP-01 انجام می‌شود؛ یعنی Let's Encrypt باید بتواند از راه همان دامنه به پورت ۸۰ سرور شما برسد. DNS منتشرنشده، رایج‌ترین دلیل شکست صدور گواهی است.

گام ۶: ساخت اولین Proxy Host

در پنل، از مسیر Hosts → Proxy Hosts → Add Proxy Host فرم را پر کنید:

  • Domain Names: n8n.domain.com
  • Scheme: http — ارتباط میان NPM و سرویس داخلی روی شبکه‌ی داکر است و رمزنگاری در لبه (میان کاربر و NPM) انجام می‌شود.
  • Forward Hostname / IP: نام کانتینر، مثلاً n8n
  • Forward Port: پورت داخلی سرویس، مثلاً 5678
  • Block Common Exploits: فعال
  • Websockets Support: فعال

گزینه‌ی WebSocket را دست‌کم نگیرید. بدون آن، سرویس‌هایی مثل n8n یا رابط‌های چت بالا می‌آیند اما به‌روزرسانی زنده، لاگ لحظه‌ای و پاسخ‌های جریانی کار نمی‌کنند و کاربر فکر می‌کند برنامه هنگ کرده است.

برای اینکه NPM بتواند کانتینر را با نام صدا بزند، آن کانتینر باید در شبکه‌ی proxy باشد:

docker network connect proxy n8n

اگر سرویس شما با docker compose اجرا می‌شود، به‌جای دستور بالا شبکه‌ی proxy را در فایل compose همان سرویس اضافه کنید تا با هر بازسازی حفظ شود.

سرویس‌هایی که روی خود سرور اجرا می‌شوند

اگر سرویس داخل داکر نیست (مثلاً یک برنامه که مستقیم روی سرور روی پورت ۳۰۰۰ گوش می‌دهد)، نام کانتینر معنا ندارد. در این حالت در فیلد Forward Hostname آی‌پی سرور روی شبکه‌ی داکر (172.17.0.1) را بگذارید و مطمئن شوید سرویس روی 0.0.0.0 گوش می‌دهد، نه فقط 127.0.0.1.

گام ۷: صدور گواهی SSL رایگان

در همان فرم Proxy Host به زبانه‌ی SSL بروید:

  • SSL Certificate: Request a new SSL Certificate
  • Force SSL: فعال — همه‌ی ترافیک HTTP به HTTPS هدایت می‌شود.
  • HTTP/2 Support: فعال
  • HSTS Enabled: فعال (فقط وقتی مطمئن‌اید این دامنه همیشه HTTPS خواهد بود)
  • ایمیل خود را وارد و شرایط Let's Encrypt را بپذیرید.

پس از چند ثانیه گواهی صادر می‌شود و در ستون SSL جدول، تاریخ انقضا نمایش داده می‌شود. تمدید خودکار را خود NPM انجام می‌دهد و نیازی به تنظیم cron نیست.

اگر صدور گواهی شکست خورد، به‌ترتیب این سه مورد را بررسی کنید: انتشار رکورد DNS، باز بودن پورت ۸۰ روی فایروال، و اینکه هیچ سرویس دیگری پورت ۸۰ را نگرفته باشد.

گام ۸: فایروال و نکته‌ی مهم داکر

اگر UFW را طبق راهنمای امن‌سازی سرور لینوکس تنظیم کرده‌اید، قواعد را کامل کنید:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw status verbose

نکته‌ای که خیلی‌ها را غافلگیر می‌کند: پورت‌هایی که داکر با -p منتشر می‌کند، مستقیم در iptables ثبت می‌شوند و از کنار UFW رد می‌شوند. یعنی اگر کانتینری را با -p 5678:5678 بالا بیاورید، آن پورت از اینترنت در دسترس است، حتی اگر UFW بگوید بسته است. راه درست این است که سرویس‌های پشت پراکسی هیچ پورتی منتشر نکنند و فقط در شبکه‌ی proxy باشند؛ همان‌طور که در گام ششم انجام دادیم.

پس از انتقال یک سرویس به پشت NPM، انتشار پورت قدیمی آن را بردارید. برای سرویس‌های compose یعنی حذف بخش ports و برای docker run یعنی حذف سوئیچ -p هنگام بازسازی کانتینر.

محدود کردن دسترسی با Access List

برای پنل‌های مدیریتی که نمی‌خواهید در دسترس همه باشند، NPM یک قابلیت آماده دارد: از مسیر Access Lists یک فهرست با نام کاربری و رمز (Basic Auth) بسازید یا دسترسی را به چند آی‌پی مشخص محدود کنید، سپس در تنظیمات Proxy Host آن را انتخاب کنید. این کار یک لایه‌ی احراز هویت پیش از رسیدن درخواست به خود سرویس اضافه می‌کند.

نگهداری: به‌روزرسانی و بک‌آپ

به‌روزرسانی یعنی تغییر شماره‌ی نسخه در فایل compose و اجرای دو دستور:

cd /opt/npm
docker compose pull
docker compose up -d

بک‌آپ ساده است چون همه‌چیز در دو پوشه است:

tar czf /root/npm-backup-$(date +%F).tar.gz -C /opt/npm data letsencrypt

این آرشیو شامل پیکربندی همه‌ی دامنه‌ها، کاربران پنل و گواهی‌هاست. برای بک‌آپ منظم و خارج از سرور، راهنمای بک‌آپ خودکار سرور با Restic دقیقاً همین پوشه‌ها را پوشش می‌دهد. پیش از هر به‌روزرسانی هم گرفتن یک اسنپ‌شات از کنترل پنل ابر سپهر سریع‌ترین راه بازگشت است.

کار دستور چه زمانی
مشاهده لاگ docker compose logs -f هنگام شکست صدور گواهی
بررسی انتشار DNS dig +short sub.domain.com پیش از ساخت Proxy Host
اتصال کانتینر به شبکه docker network connect proxy <name> هنگام افزودن سرویس جدید
به‌روزرسانی docker compose pull && docker compose up -d ماهانه
بک‌آپ پیکربندی tar از data و letsencrypt پس از هر تغییر مهم

جمع‌بندی

با نصب Nginx Proxy Manager، افزودن هر سرویس جدید به سرور از «نوشتن فایل پیکربندی و اجرای Certbot» به «پر کردن یک فرم» تبدیل می‌شود، و همه‌ی دامنه‌ها با گواهی رایگان و تمدید خودکار بالا می‌آیند.

سه تصمیمی که بیشترین تفاوت را می‌سازند: منتشر نکردن پنل مدیریت روی اینترنت و استفاده از تونل SSH، عوض کردن فوری رمز پیش‌فرض، و برداشتن انتشار مستقیم پورت سرویس‌ها تا تنها راه رسیدن به آن‌ها عبور از پراکسی باشد.

اگر می‌خواهید چند سرویس را روی یک سرور جمع کنید، از صفحه خرید سرور ابری شروع کنید؛ با همین الگو می‌توانید ده‌ها دامنه را روی یک آی‌پی و با یک پنل مدیریت کنید.

مقالات مرتبط