
آموزش n8n: راهنمای کامل اتوماسیون با هوش مصنوعی و ساخت ایجنت
یک راهنمای جامع برای ساخت عاملهای هوش مصنوعی قدرتمند و خودکارسازی فرآیندهای سازمانی با n8n، پلتفرم منعطف مبتنی بر گره.
ادامه مطلبنصب n8n روی سرور ایران با Docker Compose، PostgreSQL و HTTPS؛ از میرور داخلی داکر، پشتیبانگیری و ارتقا تا مدل محلی Ollama و تاریخ شمسی در ورکفلو.

این راهنما برای توسعهدهندهها، تیمهای فناوری اطلاعات و سازندگان ورکفلو نوشته شده است که میخواهند n8n را روی سرور مجازی یا سرور سازمانی داخل ایران اجرا کنند. خروجی کار یک نصب واقعی و قابل نگهداری است، نه یک نمونه آزمایشی: n8n با پایگاه داده PostgreSQL، اجراکننده جداگانه کد (task runner)، گواهی HTTPS با Caddy، نسخههای ثابت، پشتیبانگیری قابل بازیابی و مسیری برای اتصال مدلهای محلی هوش مصنوعی. اگر با عبارت «هاست n8n» یا «n8n ایرانی» به این صفحه رسیدهاید، منظور همین است: همان n8n رسمی، روی زیرساختی که از داخل ایران در دسترس است و کنترلش دست خودتان است.
این متن در ۲ مهر ۱۴۰۵ / ۲۴ سپتامبر ۲۰۲۶ با مستندات رسمی n8n، داکر (Docker)، Caddy و Ollama و مستندات ارائهدهندگان ابری ایرانی بازبینی شد. در این تاریخ نسخه پایدار n8n برابر 2.40.6 بود. فرمانها برای Ubuntu 24.04 نوشته شدهاند. هرجا عبارت «توصیه ما» آمده، تجربه مهندسی ماست و رفتار پیشفرض محصول نیست. این راهنما هیچ دستورالعملی برای دورزدن محدودیتهای جغرافیایی سرویسهای خارجی ندارد؛ تکیهاش بر میرورهای داخلی، میزبانی مستقل و مدلهایی است که روی سرور خودتان اجرا میشوند.
تصویر رسمی n8n از ویرایشگر ورکفلو با گره AI Agent؛ منبع: مخزن رسمی n8n در GitHub
اگر هنوز با مفاهیم پایه مثل گره، محرک، قرارداد داده و تلاش مجدد آشنا نیستید، پیش از این متن آموزش n8n و طراحی ورکفلو تولیدی را بخوانید. این مقاله فقط به ساخت و نگهداری سرور میپردازد و طراحی ورکفلو را به آن راهنما میسپارد.
نسخه خودمیزبان n8n با مجوز Sustainable Use License منتشر میشود که n8n آن را «مجوز Community» مینامد. بر اساس پرسشهای متداول مجوز n8n، استفاده داخلی در کسبوکار، اجرای چند نمونه، استفاده پشت صحنه در محصول خودتان و دریافت هزینه برای مشاوره و آموزش مجاز است. در مقابل، میزبانی n8n بهعنوان سرویس برای مشتریانی که خودشان ورکفلو میسازند، برداشتن نشان تجاری n8n و فروش آن با نام دیگر مجاز نیست.
این نکته برای بازار ایران مهم است. شرکتی که n8n را برای تیمهای خودش نصب میکند مشکلی ندارد. اما ارائهدهندهای که «هاست n8n» میفروشد و به هر مشتری یک ویرایشگر کامل میدهد، باید پیش از فروش با خود n8n درباره مجوز تجاری مکاتبه کند. این برداشت ما از متن مجوز است، نه مشاوره حقوقی.
n8n در راهنمای رسمی نصب با Docker Compose صریحاً میگوید میزبانی مستقل به دانش راهاندازی سرور، مدیریت منابع و امنسازی نیاز دارد و خطا در آن میتواند به ازدسترفتن داده و قطعی منجر شود. پس این متن را برای کسی نوشتهایم که با خط فرمان لینوکس راحت است، مالک یک دامنه است و میپذیرد که پشتیبانگیری و بهروزرسانی از این به بعد کار خودش است.
سه مسیر رایج وجود دارد و هرکدام هزینه عملیاتی متفاوتی دارد:
| مسیر | مناسب برای | نکته اصلی |
|---|---|---|
| سرور مجازی (VPS) در دیتاسنتر ایران | تیمی که کنترل کامل میخواهد | همه چیز از سیستمعامل تا پشتیبان با شماست |
| کانتینر ابری با اپلیکیشن آماده | آزمایش سریع یا تیم بدون مدیر سرور | کنترل کمتر روی تنظیمات، پشتیبان و مقیاس |
| سرور داخل شبکه سازمان | داده حساس و سیستمهای داخلی | برای وبهوکهای بیرونی به مسیر ورودی عمومی نیاز دارید |
برای مسیر دوم، آروانکلاد در مستندات خود اپلیکیشن آماده n8n در کانتینر ابری را معرفی کرده که با یک کلیک مستقر میشود و روی دامنه رایگان آروان یا دامنه اختصاصی شما در دسترس است. این مسیر برای شروع خوب است، اما پیش از جابهجایی ورکفلوهای مهم، بپرسید پشتیبان پایگاه داده و کلید رمزنگاری کجا نگهداری میشود و آیا میتوانید متغیرهای محیطی را خودتان تنظیم کنید. بقیه این راهنما مسیر اول را دنبال میکند.
اندازه سرور، توصیه ما: برای n8n، PostgreSQL و Caddy در یک تیم کوچک، ۲ هسته پردازنده، ۴ گیگابایت حافظه و ۴۰ گیگابایت دیسک SSD نقطه شروع معقولی است. اگر قرار است مدل زبانی محلی هم روی همین سرور اجرا شود، حافظه را جداگانه حساب کنید: یک مدل ۷ میلیارد پارامتری با کوانتیزهسازی ۴ بیتی فایلی حدود ۴ تا ۵ گیگابایتی است و به حافظه آزاد بیشتری از حجم فایل نیاز دارد.
واقعیت شبکه ملی: پیش از خرید یا دستکم پیش از تحویل گرفتن سرور، دسترسی آن را آزمایش کنید. Docker Hub، مخزنهای GitHub، رجیستریهای npm و PyPI و بسیاری از APIهای خارجی ممکن است از سرور ایرانی کند، ناپایدار یا غیرقابل دسترس باشند. در جهت برعکس هم، وبهوکی که یک سرویس خارجی باید به سرور شما بفرستد ممکن است در زمان اختلال اینترنت بینالملل هرگز نرسد. چند آزمایش ساده از خود سرور:
curl -sI https://docker-mirror.liara.ir/v2/ | head -n 1
curl -sI https://registry-1.docker.io/v2/ | head -n 1
curl -sI https://api.github.com | head -n 1
getent hosts n8n.example.ir
قاعده طراحی ما این است: هر وابستگی بیرونی یک ورکفلو یا داخلی است، یا روی سرور خودتان است، یا مسیر جایگزین دارد، مثلاً ذخیره در صف و تلاش دوباره پس از برقراری ارتباط. اینترنت بینالملل را یک وابستگی ناپایدار در نظر بگیرید، نه فرض پیشفرض.
برای دسترسی، یک زیردامنه اختصاصی مثل n8n.example.ir بسازید و رکورد A آن را به نشانی IP سرور ببرید. مرجع متغیرهای استقرار n8n هشدار میدهد که اجرای n8n زیر یک مسیر فرعی پشت پراکسی معکوس میتواند در پیمایش پوشهها مشکل بسازد؛ زیردامنه سادهتر و کمدردسرتر است.
اگر سرور شما به download.docker.com دسترسی دارد، راهنمای رسمی نصب Docker روی Ubuntu را دنبال کنید. اگر ندارد، بستههای docker.io و docker-compose-v2 که خود Ubuntu در مخزن universe منتشر میکند گزینه قابل اتکاییاند و از میرورهای داخلی Ubuntu هم در دسترساند. در زمان بازبینی، مخزن بهروزرسانی Ubuntu 24.04 نسخه 29.1.3 از Docker و 2.40.3 از Compose را ارائه میکرد. مستندات Docker این بستهها را غیررسمی میداند و میگوید با بستههای Docker CE تداخل دارند؛ پس یکی از دو مسیر را انتخاب کنید و آنها را با هم مخلوط نکنید.
لیارا راهنمای تنظیم میرور Ubuntu را با قالب جدید فایلهای مخزن منتشر کرده است. نسخه زیر همان تنظیم را با یک فرمان اعمال میکند و پیش از آن از فایل فعلی نسخه پشتیبان میگیرد:
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null <<'EOF'
Types: deb
URIs: https://linux-mirror.liara.ir/repository/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://linux-mirror.liara.ir/repository/ubuntu-security
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
docker --version
docker compose version
بسیاری از ارائهدهندگان سرور مجازی در ایران تصویر سیستمعامل را از پیش به میرور خودشان وصل کردهاند. اگر apt update بدون خطا کار میکند، به تغییر مخزن نیازی نیست. روی Ubuntu 26.04 نام نسخه در سطر Suites تغییر میکند؛ آن را با نام نسخه سیستم خودتان جایگزین کنید.
اگر میخواهید بدون sudo با Docker کار کنید، کاربر را با sudo usermod -aG docker $USER به گروه docker اضافه کنید و یک بار از حساب خارج و دوباره وارد شوید. عضویت در این گروه عملاً معادل دسترسی root است؛ آن را فقط به مدیران سرور بدهید.
Docker Hub از سرورهای داخل ایران اغلب کند یا در دسترس نیست. چند ارائهدهنده داخلی کش عمومی (pull-through cache) از Docker Hub اجرا میکنند. لیارا در مستند میرور Docker Hub نشانی docker-mirror.liara.ir را معرفی میکند. در بررسی ما در ۲ مهر ۱۴۰۵، دو میرور docker.iranserver.com (ایرانسرور) و docker.arvancloud.ir (آروانکلاد) هم به API رجیستری پاسخ دادند و ایمیجهای n8nio/n8n:2.40.6، n8nio/runners:2.40.6، postgres:18، caddy:2 و ollama/ollama را ارائه کردند.
یک نکته فنی مهم که بسیاری از خطاهای نصب را توضیح میدهد: طبق مستند Docker درباره میرور رجیستری، کلید registry-mirrors فقط برای Docker Hub کار میکند و رجیستریهای دیگر را پوشش نمیدهد. برخی نمونههای رسمی n8n از نشانی docker.n8n.io/n8nio/n8n استفاده میکنند که رجیستری جداگانهای است و میرور روی آن اعمال نمیشود. در این راهنما همه جا نام Docker Hub یعنی n8nio/n8n را به کار بردهایم.
sudo mkdir -p /etc/docker
[ -f /etc/docker/daemon.json ] && sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
"registry-mirrors": [
"https://docker-mirror.liara.ir",
"https://docker.iranserver.com",
"https://docker.arvancloud.ir"
],
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
EOF
sudo systemctl restart docker
docker info | grep -A4 "Registry Mirrors"
docker pull n8nio/n8n:2.40.6
docker image inspect --format '{{index .RepoDigests 0}}' n8nio/n8n:2.40.6
دو تنظیم آخر این فایل چرخش لاگ کانتینرهاست تا لاگها دیسک سرور را پر نکنند. میرور یک طرف سوم در زنجیره تأمین نرمافزار شماست، پس نسخه را ثابت کنید و خلاصه رمزنگاری (digest) را ثبت کنید. در بررسی ما هر سه میرور برای n8nio/n8n:2.40.6 همان digest را برگرداندند که Docker Hub برمیگرداند:
sha256:9c7871d5cc4fc2565bb905e4df5bf7d6a5a4bf2f4313fb99a2b3fa380f331d7c
اگر خروجی فرمان آخر با این مقدار یکی نبود، پیش از ادامه دلیلش را پیدا کنید. برای سرورهایی که به هیچ رجیستری دسترسی ندارند، ایمیج را روی سرور دیگری از سازمان خودتان با docker save در یک فایل ذخیره و روی سرور مقصد با docker load بارگذاری کنید، سپس digest را دوباره بسنجید.
ساختار پیشنهادی ما یک پوشه در /opt/n8n است که فایلهای پیکربندی، پوشه فایلهای مشترک و پشتیبانها را کنار هم نگه میدارد:
sudo mkdir -p /opt/n8n/local-files /opt/n8n/backups /opt/n8n/models
sudo chown -R "$USER":"$USER" /opt/n8n
sudo chown 1000:1000 /opt/n8n/local-files
cd /opt/n8n
کاربر داخل کانتینر n8n شناسه ۱۰۰۰ دارد؛ به همین دلیل مالکیت local-files را به او دادهایم. حالا فایل .env را با رازهای تصادفی بسازید. رشتههای hex را انتخاب کردهایم تا نویسه خاصی در رمزها مشکل نقلقول ایجاد نکند:
cat > .env <<EOF
N8N_VERSION=2.40.6
N8N_DOMAIN=n8n.example.ir
POSTGRES_USER=pgadmin
POSTGRES_PASSWORD=$(openssl rand -hex 24)
POSTGRES_DB=n8n
POSTGRES_NON_ROOT_USER=n8n
POSTGRES_NON_ROOT_PASSWORD=$(openssl rand -hex 24)
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
N8N_RUNNERS_AUTH_TOKEN=$(openssl rand -hex 32)
EOF
chmod 600 .env
کلید N8N_ENCRYPTION_KEY مهمترین راز این نصب است. n8n با آن اعتبارنامهها را پیش از ذخیره در پایگاه داده رمزنگاری میکند. اگر گم شود، پشتیبان پایگاه داده هم اعتبارنامهها را برنمیگرداند. یک نسخه از فایل .env را بیرون از سرور، در گاوصندوق رمز سازمان نگه دارید.
اسکریپت زیر همان اسکریپت نمونه رسمی در مخزن n8n-hosting است و یک کاربر غیرمدیر برای n8n در PostgreSQL میسازد. آن را با نام init-data.sh ذخیره کنید:
#!/bin/bash
set -e;
if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER ${POSTGRES_NON_ROOT_USER} WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_NON_ROOT_USER};
GRANT CREATE ON SCHEMA public TO ${POSTGRES_NON_ROOT_USER};
EOSQL
else
echo "SETUP INFO: No Environment variables given!"
fi
و این فایل compose.yaml است:
name: n8n
x-n8n-env: &n8n-env
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: "5432"
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
DB_POSTGRESDB_USER: ${POSTGRES_NON_ROOT_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_NON_ROOT_PASSWORD}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_HOST: ${N8N_DOMAIN}
N8N_PORT: "5678"
N8N_PROTOCOL: https
N8N_EDITOR_BASE_URL: https://${N8N_DOMAIN}/
N8N_WEBHOOK_URL: https://${N8N_DOMAIN}/
N8N_PROXY_HOPS: "1"
GENERIC_TIMEZONE: Asia/Tehran
TZ: Asia/Tehran
NODE_ENV: production
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
N8N_RUNNERS_MODE: external
N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0
N8N_BLOCK_ENV_ACCESS_IN_NODE: "true"
N8N_RESTRICT_FILE_ACCESS_TO: /files
N8N_DIAGNOSTICS_ENABLED: "false"
N8N_VERSION_NOTIFICATIONS_ENABLED: "false"
N8N_TEMPLATES_ENABLED: "false"
services:
postgres:
image: postgres:18
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_NON_ROOT_USER: ${POSTGRES_NON_ROOT_USER}
POSTGRES_NON_ROOT_PASSWORD: ${POSTGRES_NON_ROOT_PASSWORD}
# Postgres 18 moved its default data directory; keep this line.
PGDATA: /var/lib/postgresql/data
volumes:
- db_data:/var/lib/postgresql/data
- ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
n8n:
image: n8nio/n8n:${N8N_VERSION}
restart: unless-stopped
environment:
<<: *n8n-env
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
depends_on:
postgres:
condition: service_healthy
n8n-runner:
image: n8nio/runners:${N8N_VERSION}
restart: unless-stopped
environment:
N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
GENERIC_TIMEZONE: Asia/Tehran
TZ: Asia/Tehran
depends_on:
- n8n
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- n8n
volumes:
n8n_data:
name: n8n_data
db_data:
name: n8n_db_data
caddy_data:
name: n8n_caddy_data
caddy_config:
name: n8n_caddy_config
منطق مهمترین تصمیمهای این فایل:
PGDATA را حذف نکنید؛ Postgres 18 مسیر پیشفرض داده را تغییر داده و بدون این سطر پایگاه داده پس از راهاندازی دوباره خالی دیده میشود./home/node/.n8n حتی با PostgreSQL هم باید ماندگار بماند، چون فایل تنظیمات و کلید رمزنگاری در آن است. نامگذاری صریح حجمها، فرمانهای پشتیبانگیری را ساده و قابل پیشبینی میکند.n8nio/runners کد گره Code را جدا از فرایند اصلی اجرا میکند. نمونه رسمی میزبانی n8n هر دو ایمیج را روی یک نسخه ثابت میکند؛ اینجا هم هر دو از N8N_VERSION میخوانند تا همیشه با هم تغییر کنند.N8N_HOST، N8N_PROTOCOL، N8N_EDITOR_BASE_URL و N8N_WEBHOOK_URL به n8n میگویند کاربران و سرویسها از چه نشانی به آن میرسند. متغیر قدیمی WEBHOOK_URL از نسخه 2.35.0 منسوخ شده و هنوز کار میکند، اما هشدار میدهد.GENERIC_TIMEZONE زمانبندی گرههایی مثل Schedule Trigger را تعیین میکند و TZ ساعت سیستم کانتینر را. بدون آنها، زمانبندیها بر اساس نیویورک اجرا میشوند.N8N_BLOCK_ENV_ACCESS_IN_NODE را false میداند؛ یعنی گره Code و عبارتها میتوانند متغیرهای محیطی را بخوانند. در این نصب، رمز پایگاه داده و کلید رمزنگاری در محیط n8n هستند، پس آن را روشن کردهایم.فایل Caddyfile را کنار compose.yaml بسازید و دامنه و ایمیل را با مقدار خودتان جایگزین کنید:
{
email ops@example.ir
}
n8n.example.ir {
encode zstd gzip
reverse_proxy n8n:5678
}
مستند reverse_proxy در Caddy میگوید Caddy سرآیندهای X-Forwarded-For، X-Forwarded-Proto و X-Forwarded-Host را خودش تنظیم میکند و اتصال WebSocket را هم عبور میدهد. این دقیقاً همان چیزی است که راهنمای n8n برای وبهوک پشت پراکسی معکوس لازم میداند، در کنار N8N_WEBHOOK_URL و N8N_PROXY_HOPS=1 که در فایل Compose گذاشتیم. WebSocket برای بهروزرسانی زنده ویرایشگر لازم است و اگر قطع باشد، پیام قطع ارتباط را در ویرایشگر میبینید.
گواهی و اینترنت بینالملل. طبق مستند HTTPS خودکار Caddy، صدور گواهی از Let's Encrypt یا ZeroSSL به دو چیز نیاز دارد: سرور شما باید به مرکز صدور گواهی دسترسی داشته باشد و آن مرکز هم باید از بیرون به پورت ۸۰ یا ۴۴۳ سرور شما برسد. در زمان اختلال اینترنت بینالملل هر دو ممکن است قطع شوند و تمدید گواهی هم که هر چند هفته یک بار انجام میشود، شکست بخورد. سه گزینه برای این وضعیت:
tls /etc/caddy/certs/fullchain.pem /etc/caddy/certs/privkey.pem معرفی کنید. پوشه گواهی را هم در کانتینر Caddy mount کنید و تاریخ انقضا را پایش کنید.tls internal یک مرکز صدور محلی میسازد. گواهی ریشه آن را باید روی دستگاه کاربران نصب کنید./data. در هر حال حجم caddy_data را حفظ کنید تا گواهیها و وضعیت تمدید پس از راهاندازی دوباره از بین نروند.اگر سازمان شما Nginx را ترجیح میدهد، سرویس Caddy را از Compose حذف کنید، به سرویس n8n سطر ports: ["127.0.0.1:5678:5678"] را اضافه کنید و Nginx را روی خود سرور نصب کنید. سرآیندهای Upgrade و Connection برای WebSocket ضروریاند:
server {
listen 443 ssl;
server_name n8n.example.ir;
ssl_certificate /etc/letsencrypt/live/n8n.example.ir/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.ir/privkey.pem;
client_max_body_size 50m;
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-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
گواهی را با sudo certbot --nginx -d n8n.example.ir بگیرید. همان محدودیت دسترسی به مرکز صدور گواهی که برای Caddy گفتیم، اینجا هم برقرار است.
پیش از راهاندازی، دیواره آتش را تنظیم کنید. مستند Docker درباره فیلتر بستهها توضیح میدهد که ترافیک پورتهای منتشرشده کانتینر پیش از رسیدن به قواعد ufw منحرف میشود؛ یعنی اگر پورت 5678 را منتشر کنید، بستن آن در ufw اثری ندارد. به همین دلیل در فایل ما n8n پورت منتشرشده ندارد.
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
cd /opt/n8n
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f n8n
curl -fsS https://n8n.example.ir/healthz
فرمان config --quiet پیش از هر کاری خطای نگارشی فایل را نشان میدهد. در لاگ n8n باید اجرای مهاجرتهای پایگاه داده و اتصال اجراکننده کد را ببینید. پاسخ مسیر healthz باید وضعیت ok باشد.
بلافاصله پس از بالا آمدن سرویس، نشانی دامنه را در مرورگر باز کنید و حساب مالک را بسازید. تا وقتی مالک ساخته نشده، نخستین کسی که صفحه راهاندازی را کامل کند مالک نمونه میشود. رمز قوی و احراز هویت دومرحلهای را برای همین حساب و همه حسابهای بعدی فعال کنید.
راهنمای پشتیبانگیری و بازیابی n8n دو بخش را برای پشتیبان کامل لازم میداند: پوشه .n8n که کلید رمزنگاری در آن است و پایگاه داده PostgreSQL. همین راهنما تأکید میکند که خروجیهای فرمان export فقط ورکفلوها و اعتبارنامهها را دارند و کاربران، نقشها، سابقه اجرا، متغیرها و تنظیمات نمونه را ندارند. پس خروجی CLI برای جابهجایی ورکفلو خوب است، اما جای پشتیبان کامل را نمیگیرد.
این اسکریپت را با نام /opt/n8n/backup.sh ذخیره و با chmod +x اجرایی کنید:
#!/usr/bin/env bash
set -euo pipefail
cd /opt/n8n
set -a; . ./.env; set +a
STAMP=$(date +%F-%H%M)
docker compose exec -T postgres \
pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc > "backups/db-$STAMP.dump"
docker run --rm -v n8n_data:/data:ro -v /opt/n8n/backups:/backup alpine:3.20 \
tar czf "/backup/n8n-data-$STAMP.tgz" -C /data .
find backups -type f -mtime +14 -delete
و برای اجرای شبانه، این سطر را با crontab -e اضافه کنید:
15 2 * * * /opt/n8n/backup.sh >> /var/log/n8n-backup.log 2>&1
پشتیبانی که فقط روی همان سرور است، در برابر خرابی دیسک یا ازدسترفتن سرور کمکی نمیکند. فایلها را به یک فضای ذخیرهسازی ابری داخلی یا سرور دیگری در سازمان منتقل کنید و فایل .env را جدا از پشتیبانها نگه دارید. توصیه ما این است که هر سه ماه یک بار بازیابی کامل را روی یک سرور آزمایشی تمرین کنید:
docker compose stop n8n n8n-runner
docker compose exec -T postgres \
pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists < backups/db-YYYY-MM-DD-HHMM.dump
docker compose start n8n n8n-runner
پیش از این فرمانها، متغیرهای .env را با set -a; . ./.env; set +a در پوسته بارگذاری کنید و نام فایل را با پشتیبان واقعی جایگزین کنید. بازیابی فقط وقتی موفق است که n8n با همان کلید رمزنگاری بالا بیاید و اعتبارنامهها در ویرایشگر قابل استفاده باشند.
n8n تقریباً هر هفته نسخه جدید منتشر میکند. راهنمای بهروزرسانی n8n توصیه میکند دستکم ماهی یک بار بهروزرسانی کنید تا مجبور نشوید چند نسخه را یکجا جابهجا کنید، یادداشتهای انتشار را برای تغییرات ناسازگار بخوانید و ارتقا را اول روی نمونه آزمایشی امتحان کنید. روال ما:
cd /opt/n8n
./backup.sh
nano .env # set N8N_VERSION to the new stable release
docker compose pull n8n n8n-runner
docker compose up -d
docker compose logs -f n8n
چند نکته که در عمل مهم است. نسخه stable را برای تولید به کار ببرید، نه beta. نسخه n8n و اجراکننده کد همیشه با هم تغییر میکنند. n8n هنگام بالا آمدن مهاجرتهای پایگاه داده را اجرا میکند، پس برگشت به نسخه قبلی با تغییر برچسب ایمیج کافی نیست؛ برگشت امن یعنی بازیابی همان پشتیبانی که درست پیش از ارتقا گرفتهاید. ایمیج نسخه جدید را هم پیش از پنجره تعمیرات از میرور بکشید تا کندی شبکه زمان قطعی را طولانی نکند.
نمودار رسمی n8n از معماری حالت صف: نمونه اصلی، Redis، کارگرها و پایگاه داده؛ منبع: مستندات n8n
در حالت عادی یک فرایند n8n هم رابط کاربری را میگرداند و هم ورکفلوها را اجرا میکند. مستند حالت صف معماری دیگری را توضیح میدهد: نمونه اصلی محرکهای زمانی و وبهوکها را دریافت و شناسه اجرا را در Redis میگذارد، کارگرها (worker) آن را برمیدارند، اجرا میکنند و نتیجه را در پایگاه داده مینویسند. همه کارگرها باید همان کلید رمزنگاری و همان پایگاه داده را داشته باشند و اجرای حالت صف با SQLite توصیه نمیشود.
برای فعالکردن آن در همین فایل Compose، این چهار سطر را به بلوک x-n8n-env اضافه کنید:
EXECUTIONS_MODE: queue
QUEUE_BULL_REDIS_HOST: redis
QUEUE_HEALTH_CHECK_ACTIVE: "true"
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: "true"
سپس این سرویسها را زیر services اضافه کنید، redis_data را با name: n8n_redis_data به فهرست حجمها بیفزایید و redis را به depends_on سرویس n8n اضافه کنید:
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 10
n8n-worker:
image: n8nio/n8n:${N8N_VERSION}
restart: unless-stopped
command: worker --concurrency=5
environment:
<<: *n8n-env
volumes:
- n8n_data:/home/node/.n8n
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
n8n-worker-runner:
image: n8nio/runners:${N8N_VERSION}
restart: unless-stopped
environment:
N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
N8N_RUNNERS_TASK_BROKER_URI: http://n8n-worker:5679
GENERIC_TIMEZONE: Asia/Tehran
TZ: Asia/Tehran
depends_on:
- n8n-worker
هر کارگر اجراکننده کد مخصوص خودش را لازم دارد؛ الگوی بالا همان الگوی نمونه رسمی n8n است. مستند n8n همزمانی ۵ یا بیشتر را برای هر کارگر توصیه میکند، چون همزمانی کم با تعداد زیاد کارگر میتواند استخر اتصال پایگاه داده را تمام کند. محدودیت دیگر: حالت صف از ذخیره دادههای باینری روی سیستم فایل پشتیبانی نمیکند، پس اگر ورکفلوها فایل جابهجا میکنند، پیش از فعالسازی گزینههای ذخیره داده باینری را برای نسخه خودتان بررسی کنید.
توصیه ما: پیش از رفتن به حالت صف، یک نمونه را اندازهگیری کنید. اغلب گلوگاه واقعی یک API کند یا محدودیت نرخ یک سرویس بیرونی است و کارگر بیشتر فقط خطاهای محدودیت نرخ را بیشتر میکند.
نمونهای که به سیستم مالی، پیامرسان سازمانی یا پایگاه داده مشتری وصل میشود، به اندازه همان سیستمها حساس است. فهرست کوتاه ما:
NODES_EXCLUDE ببندید.2.12.0 میتوانید با N8N_SSRF_PROTECTION_ENABLED=true جلوی درخواست گرههایی مثل HTTP Request به نشانیهای داخلی را بگیرید. طبق مستند محافظت SSRF، این قابلیت بازههای خصوصی شبکه را بهطور پیشفرض میبندد؛ همان جایی که کانتینرهای داخلی Compose هستند. پس برای سرویسهای داخلی مجاز، مثل Ollama در بخش بعد، N8N_SSRF_ALLOWED_HOSTNAMES=ollama را هم تنظیم کنید. این قابلیت جایگزین دیواره آتش نیست و خود مستند هم آن را لایه دفاعی اضافه میداند. برای الگوی کاملتر، مرز شبکه در واکشی نشانی و SSRF را ببینید.N8N_PUBLIC_API_DISABLED=true خاموشش کنید.docker compose exec n8n n8n audit اجرا و نتیجه را بایگانی کنید..env فقط برای مدیر سرور.دادههای اجرا هم حساساند. n8n بهطور پیشفرض داده اجراهای قدیمیتر از ۳۳۶ ساعت را پاک میکند و حداکثر ۱۰ هزار اجرا نگه میدارد. اگر ورکفلوها داده شخصی جابهجا میکنند، این دوره را بر اساس سیاست نگهداری داده سازمان کوتاهتر کنید.
فریمی از ویدئوی رسمی Self-hosted AI Starter Kit شرکت n8n: گره AI Agent متصل به Ollama Chat Model و Postgres Chat Memory؛ منبع: مخزن رسمی n8n در GitHub
گرههای هوش مصنوعی n8n به یک مدل زبانی نیاز دارند. روی سرور ایرانی، APIهای مدلهای خارجی معمولاً در دسترس نیستند و ارسال داده سازمانی به آنها هم پرسشهای حقوقی و امنیتی خودش را دارد. دو مسیر عملی باقی میماند: مدل متنباز روی سرور خودتان با Ollama، یا API یک ارائهدهنده داخلی.
مدل محلی با Ollama. این سرویس را به Compose اضافه کنید، ollama_data را با name: n8n_ollama_data به حجمها بیفزایید و پس از آزمایش، برچسب ایمیج را روی یک نسخه مشخص ثابت کنید:
ollama:
image: ollama/ollama:latest
restart: unless-stopped
volumes:
- ollama_data:/root/.ollama
- ./models:/models:ro
در n8n یک اعتبارنامه Ollama بسازید و نشانی پایه را http://ollama:11434 بگذارید. صفحه مشکلات رایج گره Ollama توضیح میدهد که وقتی هر دو در Docker هستند، localhost داخل کانتینر n8n به خود n8n اشاره میکند و باید از نام کانتینر Ollama استفاده کرد.
فرمان ollama pull مدل را از رجیستری Ollama در خارج از کشور میگیرد که ممکن است در دسترس نباشد. مستند واردکردن مدل در Ollama راه دیگری میدهد: فایل GGUF یک مدل را که از مخزن داخلی سازمان یا یک منبع داخلی معتبر گرفتهاید در پوشه /opt/n8n/models بگذارید، مجوز مدل و checksum فایل را بررسی کنید و یک Modelfile کنارش بسازید:
FROM /models/qwen2.5-7b-instruct-q4_k_m.gguf
PARAMETER temperature 0.2
docker compose exec ollama ollama create qwen-fa -f /models/Modelfile
docker compose exec ollama ollama run qwen-fa "یک جمله کوتاه فارسی درباره پشتیبانگیری بنویس."
Ollama هنگام واردکردن، مدل را کوانتیزه نمیکند؛ فایل باید از پیش کوانتیزه شده باشد. نام فایل بالا فقط نمونه است. کیفیت مدلهای باز در فارسی یکسان نیست؛ پیش از انتخاب، ۳۰ تا ۵۰ نمونه واقعی از متنهای خودتان را با پاسخ مورد انتظار جمع کنید و چند مدل را روی همان نمونهها مقایسه کنید. روی پردازنده بدون GPU، مدلهای کوچک برای دستهبندی، استخراج فیلد و خلاصهسازی کوتاه مناسباند، نه برای استدلال طولانی. برای عملیات مدلهای باز در مقیاس سازمانی، راهنمای عملیات مدلهای متنباز را ببینید.
API ارائهدهنده داخلی. برخی ارائهدهندگان ایرانی نقطه دسترسی سازگار با API شرکت OpenAI ارائه میکنند. در n8n اعتبارنامه OpenAI فیلدی به نام Base URL دارد که میتوانید آن را به نشانی آن ارائهدهنده تغییر دهید و از گره OpenAI Chat Model استفاده کنید. پیش از اتصال بپرسید دقیقاً چه مدلی پشت آن نقطه دسترسی اجرا میشود، روی چه زیرساختی و در کدام کشور، دادهها چقدر نگهداری میشوند و مجوز مدل و شرایط سازنده آن استفاده شما را مجاز میداند یا نه. توصیه ما مدلهای بازی است که ارائهدهنده روی زیرساخت داخلی خودش اجرا میکند. برای مقایسه گزینههای داخلی، راهنمای پلتفرمهای هوش مصنوعی ایرانی را ببینید.
یک ورکفلو کوچک اما واقعی: فرم تماس سایت پیام فارسی را به n8n میفرستد، n8n متن را یکدست میکند، زمان دریافت را به تاریخ شمسی تهران ثبت میکند، با مدل محلی موضوع پیام را دستهبندی میکند و پاسخ میدهد. چهار گره:
contact-fa، احراز هویت Header Auth و گزینه پاسخ Using Respond to Webhook Node.کد گره Code نویسههای عربی «ي» و «ك» را به «ی» و «ک» فارسی تبدیل میکند، رقمهای فارسی و عربی شماره تلفن را لاتین میکند و زمان را هم به صورت ISO و هم شمسی نگه میدارد:
const toLatinDigits = (value) =>
String(value ?? '')
.replace(/[۰-۹]/g, (d) => String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d)))
.replace(/[٠-٩]/g, (d) => String('٠١٢٣٤٥٦٧٨٩'.indexOf(d)));
const normalizePersian = (value) =>
String(value ?? '')
.replace(/ي/g, 'ی')
.replace(/ك/g, 'ک')
.replace(/\s+/g, ' ')
.trim();
return $input.all().map((item) => {
const body = item.json.body ?? {};
const receivedAt = DateTime.now().setZone('Asia/Tehran');
const jalali = receivedAt.reconfigure({ outputCalendar: 'persian' });
return {
json: {
name: normalizePersian(body.name),
message: normalizePersian(body.message),
phone: toLatinDigits(body.phone).replace(/\D/g, ''),
receivedAt: receivedAt.toISO(),
receivedAtJalali: jalali.toFormat('yyyy/MM/dd HH:mm'),
receivedAtLabel: jalali.setLocale('fa-IR').toFormat('d MMMM yyyy'),
},
};
});
طبق مستند تاریخ و زمان در n8n، n8n برای تاریخ از کتابخانه Luxon استفاده میکند و DateTime و $now در گره Code و عبارتها در دسترساند. ما این کد را با Luxon نسخه ۳ آزمایش کردیم: برای ۲۴ سپتامبر ۲۰۲۶، مقدار receivedAtJalali با 1405/07/02 آغاز شد و receivedAtLabel برابر «۲ مهر ۱۴۰۵» بود. اگر فقط در یک گره Set یا در متن پیام به تاریخ نیاز دارید، این عبارت کافی است:
{{ $now.setZone('Asia/Tehran').setLocale('fa').reconfigure({ outputCalendar: 'persian' }).toFormat('yyyy/MM/dd') }}
با setLocale('fa') خروجی رقم فارسی دارد، مثل ۱۴۰۵/۰۷/۰۲، و بدون آن رقم لاتین. سه قاعده که بعداً دردسر نمیسازد: در پایگاه داده همیشه زمان ISO را ذخیره کنید و تاریخ شمسی را فقط برای نمایش بسازید؛ رشته شمسی فقط وقتی درست مرتب میشود که ماه و روز دو رقمی باشند؛ و نیمفاصله را حذف نکنید. کد بالا فاصلههای تکراری را یکی میکند اما به نیمفاصله دست نمیزند.
در دستور گره Basic LLM Chain متن پیام را با عبارت {{ $json.message }} بدهید و صریحاً بخواهید فقط یکی از چهار برچسب را برگرداند. خروجی مدل را پیش از هر اقدام بعدی با یک گره If یا Switch با فهرست برچسبها مقایسه کنید؛ پاسخ خارج از فهرست باید به صف بررسی انسانی برود. ورکفلو را اینطور آزمایش کنید:
curl -sS -X POST "https://n8n.example.ir/webhook-test/contact-fa" \
-H "Content-Type: application/json; charset=utf-8" \
-H "X-Webhook-Token: <your-token>" \
--data '{"name":"علي رضايي","message":"سلام، فاكتور ۱۲۳ هنوز نرسيده","phone":"۰۹۱۲-۳۴۵-۶۷۸۹"}'
نشانی webhook-test فقط وقتی کار میکند که ویرایشگر منتظر اجرای آزمایشی است. پس از فعالکردن ورکفلو از نشانی webhook استفاده کنید. ویرایشگر n8n چپبهراست است و متن فارسی در آن گاهی با علامتگذاری جابهجا نمایش داده میشود؛ این فقط مشکل نمایش است و داده را تغییر نمیدهد. خروجی HTML، مثلاً ایمیل یا پاسخ وبهوک، را در عنصری با dir="rtl" و lang="fa" بپیچید و نوع محتوا را با charset=utf-8 اعلام کنید.
اگر میخواهید چنین اتوماسیون با هوش مصنوعی را از یک ورکفلو آزمایشی به فرایندهای واقعی چند تیم برسانید، از طراحی قرارداد داده تا انتخاب مدل و پایش، خدمات مشاوره و پیادهسازی هوش مصنوعی ژرف برای همین مرحله طراحی شده است.
| نشانه | علت محتمل | راه حل |
|---|---|---|
docker pull معطل میماند یا خطای دسترسی میدهد | میرور تنظیم نشده یا نام ایمیج به رجیستری دیگری اشاره میکند | daemon.json را بررسی کنید و از n8nio/n8n استفاده کنید |
نشانی وبهوک در ویرایشگر localhost:5678 است | متغیرهای نشانی عمومی تنظیم نشدهاند | N8N_WEBHOOK_URL، N8N_HOST و N8N_PROTOCOL را بررسی کنید |
| ویرایشگر پیام قطع ارتباط میدهد | WebSocket از پراکسی عبور نمیکند | در Nginx سرآیندهای Upgrade و Connection را اضافه کنید |
| ورود با HTTP ساده ممکن نیست | کوکی امن فقط روی HTTPS فرستاده میشود | به جای خاموشکردن N8N_SECURE_COOKIE، گواهی را درست کنید |
| اعتبارنامهها پس از بازیابی باز نمیشوند | کلید رمزنگاری با نصب قبلی یکی نیست | همان N8N_ENCRYPTION_KEY قبلی را برگردانید |
| گره Code اجرا نمیشود | اجراکننده کد متوقف است یا نسخه یا توکنش فرق دارد | لاگ n8n-runner و برابری N8N_VERSION را بررسی کنید |
| گواهی صادر یا تمدید نمیشود | مرکز صدور یا پورت ورودی از خارج در دسترس نیست | از گواهی ارائهدهنده داخلی یا tls internal استفاده کنید |
| گره Ollama خطای ECONNREFUSED میدهد | نشانی localhost به کانتینر n8n اشاره میکند | نشانی پایه را http://ollama:11434 بگذارید |
| زمانبندیها با ساعت اشتباه اجرا میشوند | منطقه زمانی تنظیم نشده | GENERIC_TIMEZONE=Asia/Tehran را بررسی کنید |
| وبهوک سرویس خارجی هرگز نمیرسد | ترافیک ورودی از خارج قطع است | از محرک دورهای یا سرویس داخلی استفاده کنید |
این راهنما در ۲ مهر ۱۴۰۵ / ۲۴ سپتامبر ۲۰۲۶ با منابع رسمی زیر بازبینی شد. در دسترس بودن میرورها و digest ایمیجها را در همان روز خودمان سنجیدیم؛ این بررسی از بیرون شبکه سرور شما انجام شده و باید روی سرور خودتان تکرار شود.

یک راهنمای جامع برای ساخت عاملهای هوش مصنوعی قدرتمند و خودکارسازی فرآیندهای سازمانی با n8n، پلتفرم منعطف مبتنی بر گره.
ادامه مطلب
راهنمای عملی هوش مصنوعی در اکسل برای تیم مالی و عملیات: کار واقعی Copilot، وضعیت دسترسی در ایران، پاکسازی داده فارسی، تاریخ شمسی، آزمون فرمول و مسیر محلی با Ollama.
ادامه مطلب
هوش مصنوعی ممکن است همه رقمها را درست بخواند و معنای جدول را گم کند. پیش از پذیرش گزارش، رابطه هر عدد با سرستون، واحد و یادداشت مربوط به آن را بررسی کنید.
ادامه مطلباگر میخواهید ایجنتهای هوش مصنوعی و اتوماسیون این راهنما را در تیم نرمافزار یا فرایندهای سازمانتان به کار بگیرید، با یک پایلوت کوچک و قابل اندازهگیری شروع کنید.