استضافة n8n على VPS عبر Docker وHTTPS
شغّل n8n على VPS باستخدام Docker Compose وPostgres وHTTPS خلف reverse proxy، وتجنب خطأ WEBHOOK_URL ومفتاح التشفير، مع نصوص الأخطاء كاملة.
ما الذي ستبنيه
n8n أداة لأتمتة سير العمل: محرر مرئي يؤدي فيه مشغّل أو webhook أو جدول زمني أو إرسال نموذج إلى تشغيل سلسلة من العقد التي تستدعي واجهات API، وتعيد تشكيل البيانات، وتكتبها في أنظمة أخرى. أصبح n8n أداة الربط الافتراضية لسير عمل الوكلاء المعتمدين على الذكاء الاصطناعي، لأنه يتصل بكل مزوّدي النماذج وقواعد البيانات دون أن تكتب خدمة مخصصة. يمنحك docker run محرراً يعمل خلال دقيقتين. يتناول هذا الدليل نسبة التسعين بالمئة الأخرى: جعل n8n متيناً باستخدام Postgres بدلاً من ملف SQLite الافتراضي، وإتاحته عبر HTTPS، والأهم، وهو الجزء الذي يخطئ فيه معظم المستخدمين، جعل webhooks تُصدر عنوان URL يمكن للعالم الخارجي الوصول إليه فعلياً.
تتكون الحزمة النهائية من حاويتين على شبكة Docker واحدة: حاوية n8n نفسها، وحاوية قاعدة بيانات Postgres التي تخزن سير العمل وبيانات الاعتماد. ينهي reverse proxy على المضيف اتصال TLS ويوجّه الطلبات إلى n8n عبر localhost، لذلك لا يتصل أي مكوّن بالإنترنت إلا من خلال ذلك الـproxy. وتعمل هذه الحزمة إلى جانب الخدمات الأخرى ضمن قائمة مختصرة لاستضافة الخدمات ذاتياً في 2026.
المتطلبات الأساسية والحدود الفعلية
تحتاج إلى VPS بذاكرة RAM لا تقل عن 1 GB؛ وخطّط لاستخدام 2 GB عندما تبدأ workflows بتنفيذ أعمال فعلية، لأن عمليات التنفيذ وبيئة تشغيل Node.js تستهلكان الذاكرة، ولأن تدخّل out-of-memory killer وإيقافه الحاوية أثناء التنفيذ طريقة سيئة لاكتشاف ذلك. تكفي vCPU واحدة في البداية. إذا كان هذا الخادم سيشغّل أيضاً خدمة أكثر استهلاكاً للموارد، فحدّد حجمه وفقاً لتلك الخدمة أولاً: غالباً ما تكون مكتبة الصور هي السبب، إذ إن الحدود الفعلية لذاكرة RAM المطلوبة لـ PhotoPrism وImmich تتجاوز بكثير ما يطلبه n8n. وينطبق الأمر نفسه على خادم الوسائط: سيستهلك خادم Jellyfin وواجهة قابلة لتصفح محتواه، مثل Halcyon التي تعيد بناء المكتبة على هيئة متجر تأجير من التسعينيات، ذاكرة RAM وهامش قدرة كافياً لعمليات transcoding قبل أن يلاحظ n8n ذلك بوقت طويل.
تحتاج إلى نطاق أو نطاق فرعي، مثل n8n.example.com، مع سجل A يشير إلى عنوان IP العام لـVPS ويُحلّ قبل طلب الشهادة. يجب فتح المنفذين 80 و443 أمام الـproxy. يجب ألا يكون منفذ n8n نفسه، 5678، مكشوفاً أمام الإنترنت. تحتاج إلى Docker Engine وCompose plugin. إذا أعاد docker compose version الخطأ docker: 'compose' is not a docker command، فلديك الملف التنفيذي المستقل القديم، أما الـplugin فهو sudo apt install docker-compose-plugin.
SQLite مناسب للاختبار، أما Postgres فهو مناسب لأي شيء تعتمد عليه
قاعدة البيانات الافتراضية لـn8n هي ملف SQLite في /home/node/.n8n/database.sqlite. وهو مناسب لتجربة سريعة؛ لا تربط أي volume، وستفقد الملف عند أول إعادة إنشاء للحاوية، وهذه بحد ذاتها نتيجة مفيدة للتعلّم. سبب الانتقال إلى Postgres ليس السرعة الخام، بل أن SQLite يحتفظ بقفل كاتب واحد، لذلك فإن instance يشغّل عدة workflows في الوقت نفسه، أو وضع queue الذي ستحتاج إليه لاحقاً، سيؤدي إلى SQLITE_BUSY: database is locked عند وجود تزامن. لا يفرض Postgres هذا الحد، ويمكن إجراء نسخة احتياطية منه بوضوح باستخدام pg_dump، وهو ما تفترضه وثائق n8n نفسها لخادم تعتمد عليه. يعني الانتقال لاحقاً ترحيل البيانات يدوياً، لذلك إذا كان هذا الخادم مهماً، فابدأ باستخدام Postgres.
DNS وجدار الحماية
وجّه السجل وافتح المنافذ أولاً، حتى لا تفشل خطوة الشهادة لاحقاً بسبب اسم لا يُحلّ.
dig +short n8n.example.com
curl -s ifconfig.me
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow OpenSSH
sudo ufw enableلا تفتح المنفذ 5678. يربط ملف compose تطبيق n8n بالعنوان 127.0.0.1:5678، لذلك لا يمكن الوصول إليه إلا من خلال الـReverse Proxy على المضيف، وسيؤدي ufw allow 5678 إلى إلغاء هذا العزل.
ملف Compose
أنشئ مجلداً للعمل وملف docker-compose.yml. هذه هي الحزمة كاملة: خدمتان، وشبكة خاصة واحدة، ووحدتا تخزين مسمّاتان.
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n_net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:2.29.10
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.example.com/
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_PROXY_HOPS=1
- GENERIC_TIMEZONE=Europe/London
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_net
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
networks:
n8n_net:هناك قرارات قليلة تستحق التوضيح مباشرة. DB_POSTGRESDB_HOST=postgres هو اسم الخدمة الذي يحلّه Docker على الشبكة المشتركة، وليس localhost، الذي يعني داخل حاوية n8n حاوية n8n نفسها. يمنع depends_on مع condition: service_healthy بدء n8n قبل جاهزية Postgres عند الإقلاع؛ فمن دونه يبدأ n8n، ولا يعثر على قاعدة بيانات، ثم يتوقف. تحتوي وحدة التخزين المسمّاة n8n_data والمركّبة على /home/node/.n8n على مفتاح التشفير، وعلى قاعدة البيانات عند استخدام SQLite. وهذا هو الدليل الوحيد الذي يجب ألا تفقده. ثبّت صورة الحاوية على إصدار محدد بدقة، ولا تستخدم latest مطلقاً؛ ترد الأسباب في قسم الترقية أدناه.
ملف الأسرار
لا تضع كلمات المرور في ملف Compose. ضعها في ملف .env بجواره، إذ يقرأه Compose تلقائياً. أنشئ كلمات المرور بحيث تكون عشوائية فعلاً.
printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)" > .env
printf 'N8N_ENCRYPTION_KEY=%s\n' "$(openssl rand -hex 32)" >> .env
chmod 600 .envيُعد N8N_ENCRYPTION_KEY أهم سلسلة نصية هنا. فهو المفتاح الذي تُشفَّر به كل بيانات الاعتماد المخزّنة. عيّنه صراحةً بدلاً من السماح لـn8n بإنشائه، لأن القيمة التي أنشأتها بنفسك يمكنك تدوينها واستعادتها. بعد أن يشفّر n8n أول بيانات اعتماد باستخدام هذا المفتاح، سيؤدي تغييره إلى جعل جميع بيانات الاعتماد غير قابلة لفك التشفير. لذلك عيّنه مرة واحدة الآن، ولا تعدّل هذا السطر مطلقاً.
متغيرات البيئة التي تحدد عمل webhooks
تتحكم أربعة متغيرات في كيفية تعريف n8n بنفسه أمام العالم الخارجي. ويُعد ضبطها بشكل غير صحيح أكثر أسئلة دعم n8n شيوعاً.
N8N_HOSTهو اسم المضيف العام،n8n.example.com. إذا أبقيته على القيمة الافتراضيةlocalhostخلف proxy، فسيحاول المحرر تحميل واجهة API الخاصة به منlocalhostفي متصفحك، وهذا يفشل.N8N_PROTOCOL=httpsيخبر n8n بأنه يعمل عبر TLS، ولذلك يضع السمةSecureفي ملف تعريف ارتباط الجلسة، وينشئ عناوين URL من النوعhttps://.N8N_PORT=5678هو المنفذ الذي يستمع عليه n8n داخل الحاوية. ليس هذا هو المنفذ العام؛ فالـproxy يتولى المنفذ 443.WEBHOOK_URL=https://n8n.example.com/هو المتغير الذي يسبب المشكلة غالباً. يطبع n8n عناوين webhook التي تلصقها في Stripe أو GitHub أو أي مستدعٍ خارجي، وذلك بإنشائها من هذه القيم. إذا لم يكن مضبوطاً أو كانت قيمته غير صحيحة، يعود n8n إلىN8N_HOST:N8N_PORT، ويعطيكhttps://n8n.example.com:5678/webhook/...أو، في أسوأ الحالات،http://localhost:5678/webhook/.... تُطبع هذه العناوين من دون خطأ، وتبدو معقولة، لكنها لا يمكن الوصول إليها من الإنترنت، ولذلك لا تصل طلبات المستدعي أبداً من دون ظهور خطأ واضح. اضبطه على عنوان URL الأساسي العام الدقيق، مع الشرطة المائلة الختامية، ثم تأكد من أن عقدة webhook تعرض عنوان URL من دون منفذ.
يخبر N8N_PROXY_HOPS=1 خادم Express الخاص بـn8n بأن يثق في proxy واحد أمامه. بذلك ترى ميزة تحديد معدل الطلبات وأي ميزة تقرأ عنوان IP للعميل العنوان الحقيقي بدلاً من عنوان proxy. المتغير الوحيد الذي لا تضبطه هنا عمداً هو N8N_RUNNERS_ENABLED: إذ أصبحت task runners، التي تشغّل منطق Code-node في عملية منفصلة ومعزولة، هي الإعداد الافتراضي منذ 1.69، وأصبحت إلزامية ابتداءً من سلسلة 2.x التي يثبتها هذا الدليل. لذلك أصبح خيار التفعيل القديم مهجوراً. إذا ضبطته الآن، فسيسجل n8n إشعاراً يطلب منك إزالته.
البداية الأولى
docker compose up -d
docker compose ps
docker compose logs -f n8nينتهي الإقلاع الأول السليم بسطر Editor is now accessible via:، ويعلوه سطر n8n ready on ..., port 5678. يجب أن يعرض docker compose ps الحاويتين Up، مع وضع علامة (healthy) على postgres. إذا دخل n8n في حلقة Restarting، راقب السجلات؛ فالمشكلة تكون في الغالب في اتصال قاعدة البيانات أو صلاحيات وحدة التخزين الموضحة أدناه.
TLS باستخدام Reverse Proxy
يتحدث n8n نفسه عبر HTTP العادي على المنفذ 5678؛ لذلك يجب أن تنهي جهة أمامية اتصال HTTPS. هناك خياران واضحان.
إذا كنت تشغّل عدة حاويات بالفعل، فضع n8n خلف Reverse Proxy من Traefik يصدر شهادات TLS تلقائياً باستخدام بضعة labels. سيتولى Traefik طلب الشهادة وتجديدها نيابةً عنك.
إذا كان هذا هو التطبيق الوحيد على الخادم، فسيكون إعداد virtual host في nginx مع شهادة من Let's Encrypt أبسط. استخدم إعداد Certbot وnginx لـTLS على Ubuntu 24.04 للحصول على الشهادة، ثم استخدم server block التالي:
server {
listen 443 ssl;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600;
client_max_body_size 16m;
}
}لا يمكن الاستغناء عن رأسي Upgrade وConnection "upgrade". يرسل n8n تحديثات التنفيذ المباشرة إلى المحرر عبر WebSocket. من دون هذين السطرين، تُحمّل صفحة تسجيل الدخول ثم تتوقف وتعرض رسالة فقدان الاتصال. يمنع proxy_read_timeout 3600 قطع عمليات التنفيذ الطويلة بعد مهلة nginx الافتراضية البالغة 60 ثانية. ويكمّل رأس X-Forwarded-Proto $scheme رأس N8N_PROXY_HOPS=1؛ فهو يخبر n8n بأن الطلب الأصلي استخدم HTTPS، رغم أن الـproxy يتصل به عبر HTTP العادي. وبذلك لا يقرر n8n أن الاتصال غير آمن ويرفض cookie الخاصة به.
سير العمل الأول: جعله يعمل فعلياً
افتح https://n8n.example.com/، وأنشئ حساب المالك (في القسم التالي)، وابنِ أصغر سير عمل يثبت أن المسار يعمل: استقبال webhook، وإجراء طلب HTTP، وإرجاع استجابة.
- أضف عقدة Webhook. اضبط الطريقة على
POSTوالمسار على قيمة مثلhello. ستعرض العقدة عنوانين، هما Test URL وProduction URL، وهما سبب نصف البلاغات من نوع «لا يعمل webhook». يستجيب Test URL لطلب واحد، وفقط بعد النقر على Listen for test event؛ ثم تنتهي صلاحيته. يستجيب Production URL كلما كان سير العمل Active. - أضف عقدة HTTP Request بعدها، ووجّهها إلى أي JSON API عام. يعيد طلب GET إلى
https://api.github.com/zenسلسلة نصية من سطر واحد، وهذا يكفي. - أضف عقدة Respond to Webhook، واضبط خيار Respond في عقدة Webhook على "Using Respond to Webhook node" لكي يحصل المستدعي على ناتج عقدة HTTP.
- فعّل سير العمل Active (في أعلى اليمين) واستدعِه باستخدام:
curl -X POST https://n8n.example.com/webhook/hello. يجب أن تحصل على سطر zen مجدداً: طلب POST وارد، ثم استدعاء API، ثم إرجاع الاستجابة. هذا هو شكل معظم عمليات الأتمتة الفعلية.
يستبدل الإصدار المجدول عقدة Webhook بعقدة Schedule Trigger، ويستدعي نقطة نهاية لنموذج بدلاً منها. ويُعد استخدام نموذج مستضاف ذاتياً من Ollama يعمل على VPS نفسه طريقة مرتبة لإنشاء أداة تلخيص ليلية.
إدارة المستخدمين، وليست المصادقة الأساسية
تطلب منك أدلة n8n الأقدم ضبط N8N_BASIC_AUTH_ACTIVE=true. أُزيلت هذه المتغيرات في n8n 1.0، ولا تؤدي أي وظيفة الآن. المصادقة الحالية هي حساب المالك: عند تحميل المحرر للمرة الأولى، يطلب منك n8n إنشاء حساب مالك باستخدام البريد الإلكتروني وكلمة المرور. وهذه البوابة إلزامية، ولا يوجد وضع مجهول. أنشئ الحساب مباشرة بعد أول تشغيل، وقبل أن تمنح أي شخص عنوان URL: بين docker compose up وإرسال النموذج لأول مرة، يمكن لأي شخص يصل إلى المثيل أن يستولي عليه أولاً. تُعد إضافة طبقة basic-auth على Reverse Proxy قفلاً إضافياً مناسباً، لكنها عامل مصادقة ثانٍ وليست آلية المصادقة الأساسية. يعمل حساب المالك وكل ما تبقى في هذا الدليل على الإصدار المجتمعي المجاني؛ وإذا أردت لاحقاً إضافة مستخدمين آخرين بأدوار دقيقة، أو SSO، فمن المفيد قراءة ميزات n8n التي تتطلب ترخيصاً مدفوعاً قبل أن تضع خطتك على أساسها.
النسخ الاحتياطية: مفتاح التشفير أولاً، ثم قاعدة البيانات
هناك عنصران يحتاجان إلى النسخ الاحتياطي، لكن لا يمكن استبدالهما بالسهولة نفسها.
N8N_ENCRYPTION_KEY. تُشفَّر كل بيانات الاعتماد التي تخزنها في n8n، بما في ذلك رموز API وكلمات مرور قاعدة البيانات وأسرار OAuth، عند السكون باستخدام هذا المفتاح. تصبح مسارات العمل في Postgres عديمة الفائدة من دونه: إذا استعدت قاعدة البيانات على خادم جديد باستخدام مفتاح مختلف، فلن يتمكن n8n من فك تشفير أي بيانات اعتماد، ولن تتوفر وسيلة استرداد أو إعادة ضبط. يحتوي ملف .env على المفتاح؛ انسخه إلى مكان خارج الخادم في اليوم الذي تنشئه فيه. ويُعد إدخاله في مدير كلمات المرور خياراً مثالياً. هذه هي النسخة الاحتياطية المهمة فعلاً.
قاعدة بيانات Postgres التي تحتوي على مسارات العمل وسجل التنفيذ وبيانات الاعتماد المشفّرة نفسها:
docker compose exec -T postgres pg_dump -U n8n -d n8n \
| gzip > n8n-db-$(date +%F).sql.gzشغّل ذلك وفق جدول زمني، وانسخ ملف التفريغ إلى خارج الخادم. للاستعادة على VPS جديد: شغّل المكدس مرة واحدة حتى تُنشأ قاعدة البيانات، ثم أوقف n8n، وحمّل ملف التفريغ باستخدام psql، وضع N8N_ENCRYPTION_KEY نفسه في .env، ثم شغّل n8n. يوفّر المفتاح نفسه مع ملف التفريغ مثيلاً يعمل؛ أما استخدام مفتاح جديد فينتج مسارات عمل لا يمكنها استخدام أي بيانات اعتماد.
الترقيات: ثبّت الوسم
يحدّد ملف Compose الإصدار n8nio/n8n:2.29.10 بدلاً من latest عن قصد. يُصدر n8n إصداراً فرعياً جديداً في معظم الأسابيع، ويغيّر أحياناً مخطط قاعدة البيانات أو سلوك العقد بين هذه الإصدارات، لذلك يعني latest أن عملية سحب غير مراقبة قد تثبّت لك إصداراً ينفّذ ترقية لقاعدة بياناتك فور بدء تشغيله. ثبّت إصداراً محدداً، واقرأ ملاحظات الإصدار قبل تحديثه، إذ يوضّح n8n التغييرات غير المتوافقة هناك، ثم نفّذ الترقية عن قصد:
docker compose exec -T postgres pg_dump -U n8n -d n8n | gzip > pre-upgrade.sql.gz
# edit the image tag in docker-compose.yml, then:
docker compose pull n8n
docker compose up -d n8n
docker compose logs -f n8nتكون القفزات بين الإصدارات الرئيسية هي الحالة التي يهم فيها ذلك أكثر. فعلى سبيل المثال، غيّر خط الإصدار 2.0 الإعداد الافتراضي من N8N_BLOCK_ENV_ACCESS_IN_NODE إلى true، لذلك تفقد أي عقدة Code كانت تقرأ process.env الوصول إليها بصمت إلى أن تعيد ضبطه على false؛ كما بدأ الإصدار نفسه بفرض صلاحيات صارمة على ملف الإعدادات. اقرأ صفحة التغييرات غير المتوافقة في الإصدار 2.0 قبل الانتقال بين إصدارين رئيسيين. ينفّذ n8n تلقائياً أي عمليات ترحيل مطلوبة لقاعدة البيانات عند بدء التشغيل، ولهذا تحديداً لا يُعدّ pg_dump قبل الترقية اختيارياً. وبما أن بيانات الاعتماد مخزّنة مشفّرة باستخدام مفتاح في .env، وأن البيانات موجودة في Postgres، فإن الحاويات قابلة للاستبدال: تنفّذ الترقية باستبدالها، ويمكنك التراجع بتثبيت الوسم السابق واستعادة النسخة المفرغة.
أنماط الفشل، مع النصوص التي ستظهر لك
The requested webhook "POST hello" is not registered. يظهر الخطأ 404 عند استدعاء webhook تكون سيرته غير Active، أو عند استدعاء مسار الاختبار عندما لا يكون أي طرف يستمع إليه. تستجيب مسارات الاختبار (/webhook-test/...) فقط بعد النقر على "Listen for test event"؛ أما مسارات الإنتاج (/webhook/...) فتستجيب فقط عندما يكون مفتاح سير العمل مفعّلاً. أما النظير This webhook is not registered for GET requests. Did you mean to make a POST request? فيعني أن الطريقة غير صحيحة؛ إذ تتوقع العقدة POST بينما أرسلت GET.
يظهر عنوان webhook مع :5678 أو localhost. تعرض العقدة https://n8n.example.com:5678/webhook/... أو http://localhost:5678/.... تكون قيمة WEBHOOK_URL غير مضبوطة أو خاطئة، لذلك أنشأ n8n العنوان اعتماداً على N8N_HOST:N8N_PORT بدلاً من العنوان الأساسي العام لديك. اضبط WEBHOOK_URL=https://n8n.example.com/، ثم أعد إنشاء الحاوية باستخدام docker compose up -d، وسيختفي المنفذ.
There was a problem loading init data في المتصفح. تم تحميل المحرر، لكنه لا يستطيع الوصول إلى API الخلفية الخاص به. خلف proxy، يكون السبب في الغالب قيمة خاطئة لـ N8N_HOST أو WEBHOOK_URL، أو أن proxy لا يمرر رؤوس Upgrade الخاصة بـWebSocket، أو أن N8N_PROTOCOL لا يطابق طريقة اتصالك. تحقّق من المتغيرات الأربعة المواجهة للعامة، ومن أن proxy يمرر Upgrade وConnection.
password authentication failed for user "n8n" في السجلات، مع إعادة تشغيل الحاوية. كلمة المرور التي يرسلها n8n لا تطابق كلمة المرور التي هُيئت بها قاعدة البيانات. تكمن المشكلة في أن Postgres يقرأ POSTGRES_PASSWORD فقط عند تهيئة مجلد بيانات فارغ. شغّل المكدس مرة واحدة، ثم غيّر POSTGRES_PASSWORD في .env، وسيظل volume postgres_data الحالي يحتوي على كلمة المرور القديمة. أعد القيمة الأصلية، أو، إذا لم تكن لديك بيانات تريد الاحتفاظ بها، نفّذ docker compose down وdocker volume rm على volume الخاص بـpostgres، ثم شغّله من جديد.
EACCES: permission denied, open '/home/node/.n8n/config' عند بدء التشغيل. يعمل n8n باعتباره المستخدم node (UID 1000)، ولا يستطيع الكتابة إلى مجلد الإعدادات الخاص به. تظهر هذه المشكلة عند ربط مجلد من المضيف (./n8n_data:/home/node/.n8n) يكون مملوكاً للمستخدم root. استخدم volume المسمّى الموضح أعلاه، أو نفّذ sudo chown -R 1000:1000 ./n8n_data أولاً إذا كنت مصرّاً على استخدام bind mount.
Permissions 0644 for n8n settings file /home/node/.n8n/config are too wide. Changing permissions to 0600.. بدءاً من سلسلة 2.x، يفرض n8n قيمة 0600 على ملف الإعدادات هذا افتراضياً، ويصححها تلقائياً عند الإقلاع. يعني هذا السطر في السجل أنه صحح الوضع فعلاً، ويحدث ذلك عادةً بعد استخدام bind mount أو بعد استعادة نسخت ملفاً إلى مكانه بصلاحيات متساهلة. لا يلزم اتخاذ أي إجراء؛ اضبط N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false فقط إذا كان نظام الملفات لديك لا يدعم الصلاحيات فعلياً.
Mismatching encryption keys، ويذكر السطر الكامل أن مفتاح التشفير في ملف الإعدادات /home/node/.n8n/config لا يطابق N8N_ENCRYPTION_KEY في بيئتك. يختلف المفتاح الموجود في بيئتك عن المفتاح الذي كتبه n8n في data volume أثناء تشغيل سابق. يحدث ذلك غالباً لأن n8n أنشأ مفتاحاً عشوائياً عند إقلاع سابق عندما كان المتغير غير مضبوط، ثم ضبطت لاحقاً مفتاحاً مختلفاً. أعد المفتاح الأصلي إلى .env، أو، فقط إذا لم تكن لديك بيانات اعتماد مخزنة تريد الاحتفاظ بها فعلاً، احذف ملف config داخل volume n8n_data، ودَع n8n يعيد إنشاءه، مع قبول أن بيانات الاعتماد الحالية ستصبح غير قابلة للقراءة.
رسالة تسجيل دخول عن ملفات الارتباط الآمنة: Your n8n server is configured to use a secure cookie, however you are either visiting this via an insecure URL, or using Safari. لقد ضبطت N8N_PROTOCOL=https، لكنك وصلت إلى n8n عبر HTTP عادي، وغالباً حدث ذلك عند الوصول إليه مباشرةً باستخدام عنوان IP والمنفذ بدلاً من proxy HTTPS. صِل إليه عبر https://n8n.example.com/. إذا تعذر عليك استخدام HTTPS فعلاً، اضبط N8N_SECURE_COOKIE=false فقط، ولا تفعل ذلك مطلقاً على خادم مكشوف على الإنترنت.
لإضافة نموذج لغوي إلى مهام سير العمل هذه، راجع إنشاء مهام سير عمل للذكاء الاصطناعي باستخدام Claude وn8n.
FAQ
هل أستخدم SQLite أم Postgres مع n8n؟
SQLite، وهو الإعداد الافتراضي، مناسب لتجربة n8n ولنسخة شخصية تشغّل workflow واحداً في كل مرة. انتقل إلى Postgres لأي شيء تعتمد عليه، لأن قفل الكاتب الواحد في SQLite يسبب database is locked عند التزامن، بينما يتيح Postgres إنشاء نسخ احتياطية نظيفة باستخدام pg_dump. ترحيل البيانات لاحقاً عملية يدوية، لذلك ابدأ باستخدام Postgres إذا كان الخادم مهماً.
لماذا لا تعمل webhooks في n8n إطلاقاً؟
السبب في معظم الحالات هو WEBHOOK_URL. عندما تكون القيمة غير مضبوطة أو خاطئة، يطبع n8n عناوين webhook مبنية على N8N_HOST:N8N_PORT، وتحتوي غالباً على :5678 أو localhost. تبدو هذه العناوين صحيحة، لكنها لا يمكن الوصول إليها من الإنترنت، لذلك لا تصل طلبات المستدعي أبداً. اضبط WEBHOOK_URL=https://n8n.example.com/ وتأكد من أن العقدة تعرض URL لا يحتوي على منفذ. السبب الثاني هو استدعاء webhook في workflow غير مضبوط على الحالة Active، ما يعيد The requested webhook ... is not registered.
ما الذي يجب أن أنشئ له نسخة احتياطية في n8n؟
هناك شيئان. أولاً، N8N_ENCRYPTION_KEY من ملف .env، لأن كل credential مخزّن يُشفَّر باستخدامه، وفقدانه يجعل فك تشفيرها مستحيلاً نهائياً. انسخه إلى خارج الخادم في اليوم الذي تنشئه فيه. ثانياً، pg_dump لقاعدة بيانات Postgres التي تحتوي على workflows والسجل وcredentials. تحتاج عملية الاستعادة إلى العنصرين: المفتاح نفسه وملف التفريغ.
كيف أضع n8n خلف HTTPS؟
يقدّم n8n HTTP عاديّاً على المنفذ 5678، وينهي reverse proxy الموضوع أمامه TLS. اربط n8n بـ 127.0.0.1:5678 حتى لا يتمكن من الوصول إليه إلا الـproxy، ثم استخدم Traefik مع شهادات تلقائية أو nginx مع شهادة Let's Encrypt. اضبط N8N_PROTOCOL=https وWEBHOOK_URL=https://your-host/، وتأكد من أن الـproxy يمرر رؤوس Upgrade الخاصة بـWebSocket، وإلا ستتوقف واجهة المحرر.
كيف أرقّي n8n بأمان؟
ثبّت tag محدداً للصورة بدلاً من latest، وأنشئ pg_dump أولاً لأن n8n يشغّل عمليات الترحيل تلقائياً عند بدء التشغيل. اقرأ ملاحظات الإصدار بحثاً عن التغييرات غير المتوافقة، ثم حدّث tag وشغّل docker compose pull n8n && docker compose up -d n8n. الحاوية قابلة للاستبدال، لذلك يمكنك التراجع بتثبيت tag السابق واستعادة ملف التفريغ الذي أنشأته قبل الترقية.