نصب Nginx Proxy Manager؛ چند دامنه روی یک سرور با SSL
نصب Nginx Proxy Manager با داکر برای مدیریت چند دامنه روی یک سرور ابری؛ صدور خودکار گواهی SSL رایگان، پشتیبانی WebSocket و دسترسی امن به پنل مدیریت.
در این مقاله
وقتی روی یک سرور بیش از یک سرویس اجرا میکنید، خیلی زود به یک محدودیت ساده میرسید: پورتهای ۸۰ و ۴۴۳ یکی بیشتر نیستند. 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، عوض کردن فوری رمز پیشفرض، و برداشتن انتشار مستقیم پورت سرویسها تا تنها راه رسیدن به آنها عبور از پراکسی باشد.
اگر میخواهید چند سرویس را روی یک سرور جمع کنید، از صفحه خرید سرور ابری شروع کنید؛ با همین الگو میتوانید دهها دامنه را روی یک آیپی و با یک پنل مدیریت کنید.
مقالات مرتبط
نصب Immich روی سرور ابری؛ گالری شخصی جایگزین گوگل فوتوز
نصب Immich روی سرور ابری با داکر؛ گالری خودمیزبان عکس و ویدیو با آپلود خودکار از موبایل، پراکسی معکوس Nginx، گواهی SSL رایگان و بکآپ اصولی.
ادامه مطلبآموزش نصب Coolify روی سرور ابری
نصب Coolify روی سرور ابری برای دیپلوی خودکار برنامهها، دیتابیس و داکر با یک داشبورد؛ اتصال دامنه، گواهی SSL خودکار، فایروال و بکآپ.
ادامه مطلبآموزش نصب وردپرس روی سرور اوبونتو با Nginx
راهنمای گامبهگام نصب وردپرس روی سرور اوبونتو با Nginx، پایگاه داده MariaDB، PHP-FPM و گواهی SSL رایگان تا یک سایت آماده و امن داشته باشید.
ادامه مطلب