بلاگ/نصب و راه‌اندازی n8n روی سرور مجازی و اختصاصی با Docker: پایگاه‌داده، HTTPS و مقیاس‌پذیری
به‌روز شده

نصب و راه‌اندازی n8n روی سرور مجازی و اختصاصی با Docker: پایگاه‌داده، HTTPS و مقیاس‌پذیری

1405/06/135 بازدید
نصب و راه‌اندازی n8n روی سرور مجازی و اختصاصی با Docker: پایگاه‌داده، HTTPS و مقیاس‌پذیری

نصب و راه‌اندازی n8n روی سرور مجازی و اختصاصی با Docker: پایگاه‌داده، HTTPS و مقیاس‌پذیری

n8n ابزاری برای ساخت گردش‌کارهای خودکار است؛ برای مثال می‌توانید اطلاعات یک فرم را دریافت کنید، آن را در CRM ثبت کنید، به تیم فروش پیام بدهید و نتیجه را در یک پایگاه‌داده ذخیره کنید. نسخهٔ میزبانی‌شدهٔ این ابزار برای شروع ساده است، اما نصب n8n روی سرور مجازی کنترل بیشتری روی داده‌ها، شبکه، نسخهٔ نرم‌افزار و هزینهٔ اجرا می‌دهد. در این راهنما n8n را با Docker Compose و PostgreSQL اجرا می‌کنیم، یک ریورس‌پروکسی برای HTTPS می‌سازیم و سپس سراغ سخت‌سازی، پشتیبان‌گیری و اجرای صف‌محور با Redis می‌رویم. تنظیمات برای یک سرور مجازی مناسب‌اند و با افزایش بار می‌توان همان معماری را روی سرور اختصاصی توسعه داد. نمای کلی استقرار n8n با Docker، PostgreSQL و ریورس‌پروکسی

پیش‌نیازهای نصب n8n

برای این نصب به یک سرور لینوکسی با دسترسی SSH و یک دامنه یا زیردامنه نیاز دارید. در مثال‌ها از Ubuntu یا Debian و دامنهٔ فرضی n8n.example.com استفاده می‌کنیم. رکورد A دامنه باید به IP عمومی سرور اشاره کند. Docker Engine و افزونهٔ Docker Compose را نصب کنید و از فعال بودن سرویس Docker مطمئن شوید:

docker --version
docker compose version
sudo systemctl enable --now docker

پورت‌های 80 و 443 باید در فایروال باز باشند؛ اگر با مدیریت قواعد فایروال آشنا نیستید، راهنمای تنظیم فایروال با UFW مراحل پایه را نشان می‌دهد. پورت داخلی n8n یعنی 5678 را عمومی نکنید؛ ریورس‌پروکسی درخواست‌ها را از HTTPS به این پورت می‌رساند. برای محیط عملیاتی بهتر است حداقل 2 هستهٔ پردازنده، 4 گیگابایت RAM و فضای SSD در نظر بگیرید. نصب آزمایشی با منابع کمتر هم اجرا می‌شود، اما هم‌زمانی چند گردش‌کار، پردازش فایل و اجرای Node.js می‌تواند حافظه را سریع مصرف کند.

انتخاب پایگاه‌داده و معماری استقرار

n8n برای نگهداری گردش‌کارها، اعتبارنامه‌های رمزگذاری‌شده، کاربران و سوابق اجرا به پایگاه‌داده نیاز دارد. SQLite برای آزمایش مناسب است، اما PostgreSQL برای محیط عملیاتی انتخاب مطمئن‌تری است؛ مخصوصاً وقتی پشتیبان‌گیری منظم، چند پردازش worker یا رشد حجم اجراها مطرح باشد.

روش استقرارکاربرد مناسبمزیتمحدودیت
n8n با SQLiteآزمایش و استفادهٔ شخصی سبکراه‌اندازی سریعمناسب نبودن برای حالت صف و بار بالاتر
n8n با PostgreSQLبیشتر محیط‌های عملیاتیپایداری و پشتیبان‌گیری بهترنیازمند نگهداری پایگاه‌داده
n8n، PostgreSQL و Redisاجرای پرتعداد یا چند workerتوزیع اجرای گردش‌کارهاپیچیدگی و مصرف منابع بیشتر
چند میزبان با پایگاه‌دادهٔ مدیریت‌شدهبار بالا و نیاز به افزونگیجداسازی اجزا و توسعهٔ مستقلهزینه و عملیات بیشتر

در ادامه ابتدا معماری تک‌سرور با PostgreSQL را پیاده می‌کنیم. این ساختار برای بخش بزرگی از نصب‌های کوچک و متوسط کافی است. اگر بعدها به دسترس‌پذیری بالای پایگاه‌داده نیاز پیدا کردید، می‌توان PostgreSQL را جدا کرد و Replication و Failover خودکار PostgreSQL روی دو سرور را راه‌اندازی کرد.

ساخت فایل‌های Docker Compose

یک مسیر مشخص برای پروژه بسازید و وارد آن شوید:

sudo mkdir -p /opt/n8n
sudo chown "$USER":"$USER" /opt/n8n
cd /opt/n8n

فایل .env را با مقادیر محیط خود ایجاد کنید:

N8N_DOMAIN=n8n.example.com
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=replace-with-a-long-random-password
N8N_ENCRYPTION_KEY=replace-with-a-long-random-encryption-key
GENERIC_TIMEZONE=Asia/Tehran

برای تولید رمزهای تصادفی می‌توانید از دستور زیر استفاده کنید:

openssl rand -hex 32

مقدار N8N_ENCRYPTION_KEY اهمیت زیادی دارد. n8n اعتبارنامه‌های ذخیره‌شده را با این کلید رمزگذاری می‌کند. اگر کلید را از دست بدهید، بازیابی پایگاه‌داده به‌تنهایی برای استفاده از آن اعتبارنامه‌ها کافی نخواهد بود. فایل .env را محدود کنید:

chmod 600 .env

سپس فایل compose.yaml را بسازید:

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test:
        - CMD-SHELL
        - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - backend
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_HOST: ${N8N_DOMAIN}
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      N8N_EDITOR_BASE_URL: https://${N8N_DOMAIN}
      WEBHOOK_URL: https://${N8N_DOMAIN}/
      N8N_PROXY_HOPS: 1
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${GENERIC_TIMEZONE}
      EXECUTIONS_DATA_PRUNE: "true"
      EXECUTIONS_DATA_MAX_AGE: 336
    volumes:
      - n8n_data:/home/node/.n8n
    expose:
      - "5678"
    networks:
      - frontend
      - backend
  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    depends_on:
      - n8n
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - frontend
volumes:
  postgres_data:
  n8n_data:
  caddy_data:
  caddy_config:
networks:
  frontend:
  backend:
    internal: true

در محیط عملیاتی بهتر است به‌جای latest یک نسخهٔ مشخص و آزمایش‌شده از image را ثبت کنید. این کار مانع از آن می‌شود که یک pull عادی، نسخهٔ اصلی برنامه را ناخواسته تغییر دهد.

فعال‌کردن HTTPS با Caddy

Caddy دریافت و تمدید گواهی TLS را خودکار انجام می‌دهد. برای آشنایی بیشتر با تنظیمات و گزینه‌های ریورس‌پروکسی آن، راهنمای راه‌اندازی Caddy با HTTPS خودکار را ببینید. فایل Caddyfile را در همان مسیر پروژه قرار دهید:

n8n.example.com {
    encode zstd gzip
    reverse_proxy n8n:5678 {
        flush_interval -1
    }
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}

دامنه را با مقدار واقعی جایگزین کنید. سپس کانتینرها را اجرا کنید:

docker compose pull
docker compose up -d
docker compose ps

برای بررسی راه‌اندازی n8n و صدور گواهی، لاگ‌ها را ببینید:

docker compose logs --tail=100 n8n
docker compose logs --tail=100 caddy

اکنون باید رابط n8n از نشانی https://n8n.example.com در دسترس باشد. در اولین ورود، حساب مالک را با یک گذرواژهٔ منحصربه‌فرد بسازید. مسیر درخواست از اینترنت به ریورس‌پروکسی Caddy روی پورت ۴۴۳ و از آن‌جا به کانتینر n8n روی پورت ۵۶۷۸ و پایگاه‌دادهٔ PostgreSQL در شبکهٔ داخلی

تنظیم درست Webhook و ریورس‌پروکسی

بخش مهمی از نصب n8n روی سرور مجازی، تنظیم URL عمومی webhook است. سرویس‌های خارجی مانند GitHub، Stripe یا Telegram باید بتوانند webhook را از طریق HTTPS فراخوانی کنند. مقدار WEBHOOK_URL به n8n می‌گوید URLهای قابل‌دسترسی از اینترنت را با چه دامنه‌ای بسازد. متغیر N8N_PROXY_HOPS=1 نیز مشخص می‌کند که n8n پشت یک پراکسی مورد اعتماد قرار دارد. اگر چند لایه مانند CDN و ریورس‌پروکسی دارید، تعداد hopها را براساس مسیر واقعی درخواست تنظیم کنید؛ انتخاب عدد نادرست می‌تواند تشخیص IP و پروتکل اصلی را مختل کند. پس از تغییر متغیرهای محیطی، سرویس را بازسازی کنید:

docker compose up -d --force-recreate n8n

برای آزمایش، یک گردش‌کار ساده با Webhook Trigger بسازید، آن را فعال کنید و URL عملیاتی را از بیرون سرور فراخوانی کنید. URL آزمایشی فقط هنگام گوش‌دادن ویرایشگر کار می‌کند و نباید با URL عملیاتی اشتباه گرفته شود.

سخت‌سازی سرور و کانتینرها

قرار دادن n8n پشت HTTPS شروع خوبی است، اما امنیت به همان‌جا محدود نمی‌شود. دسترسی SSH با کلید را فعال کنید و ورود مستقیم root را ببندید (راهنمای کامل: امن‌سازی دسترسی SSH به سرور لینوکس). سپس فایروال را طوری تنظیم کنید که فقط پورت‌های لازم باز باشند:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

PostgreSQL و پورت 5678 در Compose روی میزبان publish نشده‌اند. در نتیجه از اینترنت مستقیماً قابل‌دسترسی نیستند. شبکهٔ backend نیز داخلی تعریف شده تا پایگاه‌داده فقط در اختیار سرویس‌های همان شبکه باشد. به‌روزرسانی‌ها را ابتدا روی نسخهٔ پشتیبان یا محیط staging امتحان کنید. پیش از ارتقای n8n، یادداشت انتشار نسخهٔ مقصد و تغییرات ناسازگار را بررسی کنید. سپس از داده‌ها نسخهٔ پشتیبان بگیرید و image نسخهٔ جدید را دریافت کنید. اعتبارنامه‌های API را داخل Code node یا متن گردش‌کار ننویسید. آن‌ها را در بخش Credentials نگه دارید و دسترسی کاربران به پروژه‌ها و گردش‌کارها را محدود کنید. نصب community node نیز به معنی اجرای کد آن بسته روی زیرساخت شماست؛ فقط بسته‌های مورداعتماد را نصب کنید.

پشتیبان‌گیری و بازیابی

یک نسخهٔ پشتیبان قابل‌استفاده باید پایگاه‌داده، داده‌های پایدار n8n و کلید رمزگذاری را پوشش دهد. برای گرفتن dump از PostgreSQL می‌توانید بنویسید:

mkdir -p backups
docker compose exec -T postgres \
  pg_dump -U n8n -d n8n -Fc > backups/n8n-$(date +%F).dump

علاوه بر dump، از فایل .env و volume مربوط به /home/node/.n8n نیز نسخهٔ پشتیبان رمزگذاری‌شده بگیرید. این مسیر ممکن است شامل فایل‌های محلی، تنظیمات و داده‌های لازم برای nodeهای خاص باشد. فایل‌های پشتیبان را فقط روی همان سرور نگه ندارید. خرابی دیسک یا حذف اشتباه می‌تواند هم دادهٔ اصلی و هم backup محلی را از بین ببرد. یک کپی خارج از سرور با سیاست نگهداری روزانه و هفتگی داشته باشید؛ ابزارهایی مانند Restic این چرخه را خودکار می‌کنند و نمونهٔ عملی آن در پشتیبان‌گیری خودکار و رمزنگاری‌شده از سرور لینوکس با Restic توضیح داده شده است. بازیابی را دوره‌ای روی یک محیط جداگانه آزمایش کنید. وجود فایل dump تضمین نمی‌کند که فرایند restore، کلید رمزگذاری و نسخهٔ برنامه با یکدیگر سازگار باشند.

مقیاس‌پذیری با Redis و Queue Mode

در اجرای معمولی، فرایند اصلی n8n هم رابط و webhookها را مدیریت می‌کند و هم گردش‌کارها را اجرا می‌کند. با افزایش تعداد یا مدت اجراها، می‌توان اجرای گردش‌کارها را به workerها سپرد. حالت صف از Redis به‌عنوان واسطه استفاده می‌کند و وضعیت پایدار همچنان در PostgreSQL می‌ماند. برای این معماری یک سرویس Redis به Compose اضافه کنید:

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis_data:/data
    networks:
      - backend

متغیرهای زیر را هم به سرویس اصلی n8n اضافه کنید:

      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379

سرویس worker از همان image، پایگاه‌داده، Redis و کلید رمزگذاری استفاده می‌کند:

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: unless-stopped
    command: worker --concurrency=5
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${GENERIC_TIMEZONE}
    volumes:
      - n8n_data:/home/node/.n8n
    networks:
      - backend

حجم redis_data را نیز به بخش volumes اضافه کنید. برای افزایش workerها می‌توان از دستور زیر استفاده کرد:

docker compose up -d --scale n8n-worker=3

عدد concurrency را بدون اندازه‌گیری بالا نبرید. گردش‌کارهای مبتنی بر HTTP معمولاً سبک‌تر از پردازش فایل، تبدیل تصویر یا Code nodeهای سنگین هستند. مصرف CPU، RAM، زمان انتظار صف و تعداد اتصال‌های PostgreSQL را زیر نظر بگیرید.

سایزینگ سرور مجازی یا اختصاصی

منابع لازم به تعداد گردش‌کارها وابسته نیست؛ نوع nodeها، اندازهٔ داده، هم‌زمانی و مدت نگهداری سوابق اجرا تعیین‌کننده‌اند. یک گردش‌کار پردازش ویدئو ممکن است از ده‌ها گردش‌کار سبک API منابع بیشتری بخواهد.

نوع استفادهنقطهٔ شروع پیشنهادینکته
آزمایش و گردش‌کارهای سبک2 vCPU و 2 تا 4 GB RAMبرای محیط کم‌ترافیک
تیم کوچک و بار عملیاتی متوسط4 vCPU و 8 GB RAMمناسب n8n، PostgreSQL و Redis روی یک میزبان
workerهای متعدد یا پردازش سنگین8 vCPU و 16 GB RAM یا بیشتراجزا را براساس مصرف واقعی جدا کنید
بار مداوم و نیاز به توسعهٔ بیشترسرور اختصاصی یا چند میزبانپایگاه‌داده و workerها را مستقل مقیاس دهید

فضای دیسک را نیز پایش کنید. ذخیرهٔ ورودی و خروجی همهٔ اجراها می‌تواند PostgreSQL را به‌سرعت بزرگ کند. متغیرهای pruning در نمونهٔ Compose سوابق قدیمی را پاک می‌کنند، اما بازهٔ نگهداری باید با نیاز عیب‌یابی و مقررات سازمان هماهنگ شود. اگر برای شروع به زیرساختی با امکان ارتقای CPU و RAM نیاز دارید، صفحهٔ سرور مجازی ابری آریاسرویس گزینه‌های موجود را نشان می‌دهد. برای workerهای سنگین و مصرف پایدار پردازنده نیز می‌توانید سرور اختصاصی را بررسی کنید.

نگهداری روزمرهٔ n8n

پس از راه‌اندازی، سلامت کانتینرها و میزان مصرف منابع را مرتب بررسی کنید:

docker compose ps
docker stats
docker compose logs --since=1h n8n

برای ارتقا، ابتدا نسخهٔ پشتیبان بگیرید، شمارهٔ image را در Compose تغییر دهید و سرویس‌ها را دوباره ایجاد کنید:

docker compose pull
docker compose up -d

هشدار برای پرشدن دیسک، مصرف زیاد حافظه، توقف کانتینر و خطاهای مکرر گردش‌کارها تنظیم کنید. اگر webhookها زمان پاسخ طولانی دارند، اجرای کار اصلی را از پاسخ اولیه جدا کنید یا worker اضافه کنید. اگر پایگاه‌داده عامل کندی است، تعداد اتصال‌ها، queryهای طولانی، IOPS دیسک و سیاست حذف سوابق اجرا را بررسی کنید.

جمع‌بندی

برای یک نصب عملیاتی n8n، ترکیب Docker Compose، PostgreSQL و یک ریورس‌پروکسی HTTPS پایهٔ مناسبی فراهم می‌کند. پورت برنامه و پایگاه‌داده نباید مستقیم در اینترنت قرار گیرند و کلید رمزگذاری باید همراه داده‌ها، اما در محلی امن، پشتیبان‌گیری شود. تا زمانی که بار کم یا متوسط است، همهٔ اجزا می‌توانند روی یک سرور مجازی اجرا شوند. وقتی زمان انتظار صف یا مصرف منابع افزایش یافت، Redis و workerهای مستقل امکان توزیع اجراها را فراهم می‌کنند. انتخاب سرور مجازی یا اختصاصی را براساس اندازهٔ واقعی داده، هم‌زمانی گردش‌کارها و نتایج پایش انجام دهید، نه صرفاً تعداد workflowهای ثبت‌شده.