وصلنا إلى الجزء العملي الذي تقوم عليه السلسلة كلها. سننصّب Nginx Proxy Manager على حاوية LXC داخل Proxmox، ونربط به ثلاث خدمات داخلية، ونحصل لها على شهادات Let's Encrypt مجانية — كل ذلك من واجهة رسومية بلا كتابة إعدادات nginx يدوياً.
كل ما في هذه السلسلة مُنفَّذ فعلاً. بنينا المختبر على سيرفر Proxmox VE 9.2 بعنوان عام واحد، وأنشأنا عليه شبكة خاصة 10.10.10.0/24 وأربع حاويات، ونشرنا ثلاثة نطاقات فرعية حقيقية بشهادات Let's Encrypt. كل لقطة وكل مخرج أمر في هذه المقالات من ذلك المختبر — والعناوين في الصور حقيقية وقت التنفيذ.
لماذا حاوية LXC لا جهاز افتراضي؟
لأن الوسيط خدمة خفيفة جداً: يستهلك أقل من 300 ميغابايت ذاكرة ويخدم عشرات المواقع. الحاوية تقلع في ثانيتين وتستهلك جزءاً ممّا يستهلكه جهاز افتراضي كامل. الشرط الوحيد أن تفعّل فيها nesting لأننا سنشغّل Docker بداخلها.
الخطوة 1: إنشاء الحاوية
pct create 201 local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
--hostname npm \
--memory 1024 --cores 2 \
--rootfs local-lvm:8 \
--net0 name=eth0,bridge=vmbr2,ip=10.10.10.10/24,gw=10.10.10.1 \
--nameserver 1.1.1.1 \
--features nesting=1 \
--unprivileged 1 --onboot 1 --password 'كلمة-مرور-قوية'
pct start 201
العنوان 10.10.10.10 اختيار مقصود. ستكتبه في كل قاعدة تمرير وفي كل شرح لاحق. احجز للوسيط عنواناً سهل الحفظ والتزم به.
الخطوة 2: تنصيب Docker
pct exec 201 -- bash
apt-get update
apt-get install -y curl ca-certificates gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/debian trixie stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
docker --version
الخطوة 3: تشغيل Nginx Proxy Manager
mkdir -p /opt/npm && cd /opt/npm
cat > docker-compose.yml <<'YML'
services:
app:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
YML
docker compose up -d
docker ps
ثلاثة منافذ بثلاثة أدوار: 80 لطلبات HTTP وتحدّي Let's Encrypt، و443 لـHTTPS، و81 للوحة الإدارة — وهذا الأخير لا يُنشر على الإنترنت إطلاقاً.
الخطوة 4: تمرير 80 و443 من العنوان العام
iptables -t nat -A PREROUTING -d 82.39.115.50 -p tcp --dport 80 \
-j DNAT --to-destination 10.10.10.10:80
iptables -t nat -A PREROUTING -d 82.39.115.50 -p tcp --dport 443 \
-j DNAT --to-destination 10.10.10.10:443
وثبّتهما في /etc/network/interfaces بـpost-up كما في الجزء الرابع. هاتان القاعدتان هما كل ما يحتاجه سيرفرك من منافذ مفتوحة للويب — مهما بلغ عدد مواقعك.
الخطوة 5: أول دخول إلى اللوحة
لوحة الإدارة على http://10.10.10.10:81، وهي غير متاحة من الإنترنت. للوصول إليها من جهازك افتح نفقاً:
ssh -L 8181:10.10.10.10:81 [email protected]
# ثم افتح: http://localhost:8181
معلومة قديمة انتشرت كثيراً وتغيّرت: النسخ الأقدم كانت تأتي بحساب افتراضي [email protected] وكلمة مرور changeme. الإصدار 2.16 ألغى ذلك ووضع شاشة إعداد أولى بدلاً منه. إن قرأت شرحاً يطلب منك تلك البيانات فهو قديم — والشاشة أعلاه هي ما ستراه فعلاً.
الخطوة 6: ربط أول خدمة
من Hosts ← Proxy Hosts ← Add Proxy Host، واملأ ثلاثة حقول لا غير:
| الحقل | القيمة | لماذا |
|---|---|---|
| Domain Names | wp.example.com | الاسم الذي يكتبه الزائر |
| Scheme | http | الاتصال الداخلي غير مشفّر — وهذا صحيح |
| Forward Hostname / IP | 10.10.10.11 | عنوان الحاوية الخاصة |
| Forward Port | 80 | منفذ الخدمة داخل الحاوية |
| Block Common Exploits | ✅ | حجب أنماط هجوم معروفة — فعّلها دائماً |
| Websockets Support | حسب التطبيق | ضرورية لـn8n وNextcloud |
الخطوة 7: الشهادة
في تبويب SSL اختر Request a new SSL Certificate، ووافق على الشروط، وفعّل Force SSL. سيطلب NPM الشهادة من Let's Encrypt ويجدّدها تلقائياً كل 90 يوماً.
شرط نجاح الشهادة: يجب أن يكون النطاق يشير فعلاً إلى عنوانك العام، وأن يكون المنفذ 80 مفتوحاً وممرَّراً إلى الوسيط. تحدّي Let's Encrypt يمرّ عبر المنفذ 80 حتى لو كان موقعك يعمل على 443. إن كنت خلف Cloudflare بالسحابة البرتقالية، أطفئها مؤقّتاً أو استعمل تحدّي DNS — وهذا موضوع الجزء الثامن.
النتيجة بعد ربط ثلاث خدمات
هذه الصورة هي السلسلة كلها في لقطة واحدة: عمود Source يحمل الأسماء العامة، وعمود Destination يحمل العناوين الخاصة، والمنفذان 80 و443 هما كل ما فُتح على الإنترنت.
أخطاء شائعة وحلولها
| العَرَض | السبب | الحل |
|---|---|---|
| الحاوية ترفض تشغيل Docker | nesting غير مفعّل | pct set 201 --features nesting=1 ثم أعد التشغيل |
| الشهادة تفشل بخطأ تحدّي | المنفذ 80 غير ممرَّر أو DNS لم ينتشر | تحقّق من dig ومن قاعدة DNAT للمنفذ 80 |
| الموقع يفتح ثم يتجمّد | WebSocket غير مفعّل | فعّل Websockets Support للمضيف |
| خطأ 502 Bad Gateway | الخدمة الداخلية متوقّفة أو المنفذ خطأ | pct exec 202 -- ss -ltnp |
| خطأ 413 عند رفع ملف | حدّ حجم الطلب الافتراضي | في Advanced: client_max_body_size 512m; |
| حلقة تحويل لا تنتهي | التطبيق يحوّل إلى HTTPS وهو لا يعلم أنه خلف وسيط | مرّر X-Forwarded-Proto واضبط التطبيق ليثق به |
أسئلة شائعة
هل أستطيع تنصيبه بلا Docker؟
رسمياً لا — يُوزَّع كصورة Docker. إن كنت ترفض Docker فاستعمل Caddy أو nginx مباشرة.
كم موقعاً يتحمّل؟
مئات. هو nginx في جوهره، والحدّ هو موارد سيرفرك لا الوسيط.
كيف آخذ نسخة احتياطية؟
كل شيء في مجلد /opt/npm/data وletsencrypt. انسخهما — أو خذ لقطة (snapshot) للحاوية كلها من Proxmox، وهي أسهل.
هل أفتح لوحة الإدارة على نطاق فرعي؟
لا تفعل. استعمل نفق SSH كما أعلاه. وإن اضطررت فضع عليها قائمة وصول تمنع كل العناوين إلا عنوانك.
هل يدعم النطاقات الشاملة (wildcard)؟
نعم، لكن شهادة *.example.com تتطلّب تحدّي DNS لا تحدّي المنفذ 80 — وهو ما نشرحه في الجزء الثامن.
الخطوة التالية
الوسيط يعمل. في الجزء السابع نحوّل ثلاث خدمات داخلية إلى ثلاثة نطاقات فرعية حقيقية، ونعالج مشكلة «التطبيق لا يعرف أنه خلف وسيط».
هذه المقالة جزء من سلسلة «من IP واحد إلى عشرات الخدمات» — عشرة أجزاء بُنيت كلها على سيرفر Proxmox حقيقي: ١. لماذا يكفي عنوان واحد · ٢. الشبكة الخاصة · ٣. إعداد NAT · ٤. تمرير المنافذ · ٥. الـReverse Proxy · ٦. Nginx Proxy Manager · ٧. النطاقات الفرعية · ٨. Cloudflare والشهادات · ٩. مقارنة الحلول · ١٠. سحابة صغيرة كاملة