[{"data":1,"prerenderedAt":121},["ShallowReactive",2],{"seo-verification":3,"blog-install-n8n-on-vps-with-docker-complete-2026-guide-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"id":7,"slug":8,"slugs":9,"title":12,"excerpt":13,"readTime":14,"views":15,"isPinned":16,"publishedAt":17,"category":18,"categories":23,"featuredImage":25,"bgImage":26,"posterImage":27,"relatedSolution":28,"intro":31,"sections":32,"ctaTitle":98,"ctaBody":99,"ctaButton":100,"ctaUrl":101,"relatedPosts":102},3,"install-n8n-on-vps-with-docker-complete-2026-guide",{"fr":10,"en":8,"ar":11},"installer-n8n-vps","تثبيت-n8n-على-vps-مع-docker-دليل-شامل-2026","Install n8n on VPS with Docker: complete 2026 guide","Deploy n8n on VPS with Docker Compose, reverse proxy, HTTPS and webhooks. Covers V8 crash >30 workflows, 502 nginx timeout and npm to Docker migration before v3.0.",11,0,false,"2026-06-05T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":21},2,"Automation","automatisation","bg-brand-action\u002F10 text-brand-action",[24],{"id":19,"name":20,"slug":21,"color":22,"icon":21},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Finstaller-n8n-vps-poster.svg",{"categorySlug":29,"appSlug":30},"automation-workflows","n8n","n8n is an open source automation orchestrator: it connects your APIs, triggers workflows on events and, when self-hosted, runs without execution limits or cloud subscription. This guide covers the complete installation on VPS with Docker, reverse proxy configuration, critical environment variables, two critical production errors — V8 crash with more than 30 simultaneous workflows and 502 Bad Gateway nginx — and migration from npm mode, unsupported since n8n v3.0.",[33,37,48,51,76,80,83,86,89,92,95],{"type":34,"title":35,"body":36},"h2","Why host n8n on your VPS","The cloud version of n8n charges per execution beyond the plan and limits the number of active workflows. On your VPS, the only cost is that of the server, regardless of the number of automations or API calls. You also keep full control over credentials, webhook payloads and execution history — no data transits through a third-party infrastructure.",{"type":38,"title":39,"items":40},"ul","The concrete benefits of a self-hosted n8n",[41,42,43,44,45,46,47],"Unlimited executions: no monthly cap, no cost at scale.","Credentials and webhook payloads confined to your server, without external transit.","Access to community nodes and custom code execution without restriction.","Webhooks on your own domain, configurable for each inbound integration.","Predictable cost: a fixed VPS price, independent of automation volume.","Controlled persistence of workflows and history in volumes you back up.","Compatibility with Ollama, Flowise or any other Docker service on the same internal network.",{"type":34,"title":49,"body":50},"Numbered prerequisites","Before starting, verify your VPS meets the following requirements. For moderate usage, **1 vCPU and 1 GB of RAM are sufficient**; plan for **2 vCPU and 2 GB** as soon as you run heavy or concurrent workflows, and **4 GB** if you connect a dedicated PostgreSQL database or integrate a local AI model. Allow 10 GB of disk minimum for Docker, volumes and logs. Port **5678** must not be exposed directly — n8n only listens on `127.0.0.1:5678` and all requests go through the reverse proxy on port **443**. A subdomain (for example `n8n.your-domain.com`) pointing to the VPS IP is required for HTTPS and inbound webhooks. Docker Engine 24+ and Docker Compose v2 are required.",{"type":52,"title":53,"steps":54},"steps","Step-by-step installation",[55,58,61,64,67,70,73],{"title":56,"body":57},"Update the VPS and install Docker","Connect via SSH and update packages: `apt update && apt upgrade -y`. Then install Docker via the official script: `curl -fsSL https:\u002F\u002Fget.docker.com | sh`. Verify the installation: `docker --version && docker compose version`. Create the working directory: `mkdir -p \u002Fopt\u002Fn8n && cd \u002Fopt\u002Fn8n`.",{"title":59,"body":60},"Create the docker-compose.yaml file","Create `docker-compose.yaml` with the n8n service, a named volume for persistence and the essential environment variables. Declare `image: n8nio\u002Fn8n:latest`, `restart: unless-stopped`, and mount `n8n_data:\u002Fhome\u002Fnode\u002F.n8n`. Expose only on `127.0.0.1:5678:5678` to avoid any direct public exposure of the port.",{"title":62,"body":63},"Set critical environment variables","In the service `environment` section, declare at minimum: `N8N_HOST=n8n.your-domain.com`, `N8N_WEBHOOK_URL=https:\u002F\u002Fn8n.your-domain.com\u002F`, `N8N_PROXY_HOPS=1` (so n8n accepts `X-Forwarded-*` headers from the reverse proxy), `N8N_BASIC_AUTH_ACTIVE=true`, `N8N_BASIC_AUTH_USER=\u003Cyour-login>` and `N8N_BASIC_AUTH_PASSWORD=\u003Cstrong-password>`. For production use, store these values in an adjacent `.env` file and reference it via `env_file: .env`.",{"title":65,"body":66},"Start the container","Run: `docker compose up -d`. Verify the container is running: `docker compose ps`. Check logs: `docker compose logs -f n8n`. n8n is ready when the line `Editor is now accessible via: http:\u002F\u002Flocalhost:5678\u002F` appears in the logs. At this point the interface is only accessible from `127.0.0.1` — this is intentional.",{"title":68,"body":69},"Configure the reverse proxy with Caddy (recommended)","Caddy is the simplest reverse proxy for n8n: it handles the Let's Encrypt certificate and renewal without additional configuration. Install Caddy (`apt install caddy`) then edit `\u002Fetc\u002Fcaddy\u002FCaddyfile` to add: `n8n.your-domain.com { reverse_proxy localhost:5678 }`. Reload: `systemctl reload caddy`. **With nginx**, add in your `server` block: `proxy_set_header X-Forwarded-Host $host;`, `proxy_set_header X-Forwarded-Proto $scheme;` and `proxy_set_header X-Real-IP $remote_addr;` — without these headers, n8n rebuilds incorrect webhook URLs.",{"title":71,"body":72},"Verify inbound webhooks","In the n8n editor, create a test workflow with a **Webhook** node. The URL displayed in production mode must be exactly `https:\u002F\u002Fn8n.your-domain.com\u002Fwebhook\u002F\u003Cyour-path>`. Trigger the call from your local machine: `curl -X POST https:\u002F\u002Fn8n.your-domain.com\u002Fwebhook\u002Ftest -d '{}'`. If the displayed URL contains `localhost` or port `5678`, the `N8N_WEBHOOK_URL` variable is not being picked up — verify the container restarted after adding the variable.",{"title":74,"body":75},"Connect PostgreSQL for production","SQLite is fine for testing; in production, prefer PostgreSQL. Add a `postgres:15` service to the same `docker-compose.yaml`, with a dedicated `pg_data` volume. In the n8n service, add: `DB_TYPE=postgresdb`, `DB_POSTGRESDB_HOST=postgres`, `DB_POSTGRESDB_DATABASE=n8n`, `DB_POSTGRESDB_USER=n8n` and `DB_POSTGRESDB_PASSWORD=\u003Cpassword>`. Restart with `docker compose up -d`; n8n automatically migrates the schema on first startup.",{"type":77,"title":78,"body":79},"tip","Hardening and queue mode","Three production reflexes: (1) Never expose port 5678 on the public interface — keep the `127.0.0.1:5678` binding. (2) Enable authentication: in v1.x, `N8N_BASIC_AUTH_ACTIVE=true`; in v1.27+, prefer native authentication via the interface (Settings → Security). (3) For AI or long-running workflows, switch to queue mode with a separate `worker` instance and a Redis queue: this isolates long executions from the interface and allows horizontal scaling without reconfiguring webhooks.",{"type":34,"title":81,"body":82},"Fatal V8 crash with more than 30 active workflows","**Symptom.** The n8n instance crashes with the error `FATAL ERROR: invalid-mark-compact are transition` in the Docker logs. The container restarts if `restart: unless-stopped` is configured, but the crash recurs as soon as load passes the same threshold again. No error message in the interface: the container disappears without warning.\n\n**Cause.** This error is a panic in the V8 engine (the JavaScript engine embedded in Node.js) during a garbage collection cycle. It is triggered when the V8 heap is saturated — typically starting at **30 workflows executing simultaneously** on a VPS with less than 2 GB of RAM allocated to the process. Each active workflow maintains an execution context in memory; beyond a certain threshold, the GC attempts a `mark-compact` transition on an already corrupted heap, causing the fatal crash. The problem has **no** automatic recovery: n8n has no graceful degradation mechanism at this level.\n\n**Immediate fix.** Increase the V8 heap limit by adding the following environment variable in the n8n service in your `docker-compose.yaml`: `NODE_OPTIONS=--max-old-space-size=2048`. This allocates 2 GB to the V8 heap. Restart the container: `docker compose restart n8n`. Watch the logs for a few minutes to confirm the absence of crashes.\n\n**Structural fix.** The container memory limit must match the V8 limit. If your `docker-compose.yaml` declares `mem_limit: 1g` and you pass `--max-old-space-size=2048`, the OOM killer kills the container before V8 can use it. Rule: allocate **at least 2 GB of RAM to the VM** beyond 30 active workflows, and pass `NODE_OPTIONS=--max-old-space-size=1536` (leaving 512 MB for the rest of the system). For installations with more than 50 workflows, prefer **queue mode** (separate Redis worker instance) which decouples executions from the main process and distributes memory load. Source: community.n8n.io thread #308425.",{"type":34,"title":84,"body":85},"Persistent 502 Bad Gateway behind nginx","**Symptom.** Short requests succeed but some workflows return `502 Bad Gateway` from nginx — particularly workflows that call slow external APIs, process large data volumes, or chain many nodes. The 502 occurs exactly 60 seconds after execution starts, even though n8n continues working in the background.\n\n**Cause.** nginx waits by default **60 seconds** for a response from the backend before closing the connection (`proxy_read_timeout` = 60 s). For n8n, the backend is the process executing the workflow: if execution takes more than 60 seconds, nginx cuts the connection and returns a 502. n8n continues execution in the background (the workflow finishes server-side), but the client never receives the response — making it appear as a failure even though the result was produced. The behavior is worsened with synchronous webhooks that wait for the workflow to finish before responding (`Respond to Webhook` node at the end of the flow).\n\n**Fix.** Add these two directives in the `location` block of your nginx configuration proxying to n8n:\n\n`proxy_read_timeout 300;`\n`proxy_send_timeout 300;`\n\nThe value of 300 seconds (5 minutes) covers the vast majority of long workflows. For exceptionally long workflows (massive data import, multi-step AI chains), raise it to 600 s. Reload nginx: `nginx -t && systemctl reload nginx`. Note that this value does not replace the connection timeout (`proxy_connect_timeout`, keep it at 60 s — it only applies to the initial TCP connection establishment).\n\n**Verification.** Run an intentionally slow workflow (a `Wait` node set to 90 s, for example) and verify the response arrives beyond 60 seconds without error. If the 502 persists after the change, verify you edited the correct `location` block — a nginx configuration split across several `include` files may have a more specific block that overrides the timeout. Source: community.n8n.io thread #274581.",{"type":34,"title":87,"body":88},"Migrating from npm to Docker before n8n v3.0","If your instance runs via `npx n8n` or `npm install -g n8n`, **act before October 2026**. n8n v3.0 definitively drops npm\u002Fnpx mode: instances installed this way will stop receiving updates and security patches. Migration takes four steps, with no data loss.\n\n**Step 1 — Export your workflows.** In the interface, go to Settings → Import\u002FExport or use the CLI: `n8n export:workflow --all --output=workflows.json`. Also export your credentials if you wish to migrate them: `n8n export:credentials --all --output=credentials.json`.\n\n**Step 2 — Stop the npm instance.** Stop the process (`pm2 stop n8n` or `systemctl stop n8n` depending on your process manager) and note the path to the current data folder (usually `~\u002F.n8n`).\n\n**Step 3 — Deploy the Docker container** following the steps above. The `n8n_data` Docker volume is mounted at `\u002Fhome\u002Fnode\u002F.n8n` in the container. If you copy `~\u002F.n8n` directly into the volume, n8n reuses workflows and credentials without manual import.\n\n**Step 4 — Import and verify.** If you chose JSON export, import from the interface or via: `docker exec n8n n8n import:workflow --input=workflows.json`. Verify that each active workflow triggers correctly and that credentials are valid in their respective nodes.\n\n**Deadline: October 2026.** An npm instance still active after v3.0 release continues to work short-term, but receives no more updates — including security patches. Plan the migration now.",{"type":34,"title":90,"body":91},"Breaking changes to know (v1.27–v1.31)","Three changes in recent versions can silently break an existing instance.\n\n**OAuth 2.0 parameter rename in HTTP Request.** The `oauthTokenData` field was renamed in versions 1.27-1.31. Requests authenticated via OAuth 2.0 in the HTTP Request node may stop working without an explicit error message — n8n sends an unauthenticated request rather than raising an exception. Check every workflow using this node with OAuth credentials after an update.\n\n**Webhook URL format.** The format of the URL generated by Webhook nodes changed in this version range. If you have hardcoded webhook URLs in third-party services (Stripe, GitHub, Slack...), re-verify them after the update.\n\n**Deprecation of `$item()`.** The `$item()` function available in expressions and the Function node is marked deprecated. Its replacement is `$input.item` for the current item or `$('Node Name').item` for items from a previous node. It still works in v1.x but will be removed in v3.0.\n\nThe full list of breaking changes is available on the \u003Ca href=\"https:\u002F\u002Fdocs.n8n.io\u002Fchangelog\u002Fv30-breaking-changes\">official n8n documentation\u003C\u002Fa>.",{"type":34,"title":93,"body":94},"Troubleshooting common errors","**Port 5678 is unreachable.** Verify the container is running (`docker compose ps`) and that you are listening on `127.0.0.1:5678`. If testing from the local machine, `curl http:\u002F\u002F127.0.0.1:5678\u002F` should respond.\n\n**Webhooks display `localhost` instead of the domain.** The `N8N_WEBHOOK_URL` variable is missing or misconfigured. Add `N8N_WEBHOOK_URL=https:\u002F\u002Fn8n.your-domain.com\u002F` (with trailing slash) and restart: `docker compose restart n8n`.\n\n**Missing `N8N_PROXY_HOPS`: 502 error or loop.** Without this variable, n8n rejects or loops on `X-Forwarded-*` headers. Add `N8N_PROXY_HOPS=1` in the container environment.\n\n**Volume permissions error.** The n8n container runs under UID 1000. If the data folder was created by root, permissions are incorrect: `chown -R 1000:1000 \u002Fopt\u002Fn8n\u002Fdata` then `docker compose restart n8n`.\n\n**PostgreSQL refuses the connection.** Verify the postgres service is on the same Docker network as n8n (`docker network inspect \u003Cname>`) and that `DB_POSTGRESDB_HOST`, `DB_POSTGRESDB_USER` and `DB_POSTGRESDB_PASSWORD` match exactly those defined in the postgres service.\n\n**V8 fatal crash (`FATAL ERROR: invalid-mark-compact`).** The V8 memory heap is saturated: more than 30 concurrent workflows with insufficient RAM. Add `NODE_OPTIONS=--max-old-space-size=2048` in the n8n service environment and increase VPS RAM to at least 2 GB. See the dedicated section above.\n\n**Persistent 502 Bad Gateway (exactly 60 s).** The nginx `proxy_read_timeout` is at its default (60 s). Raise it to 300 s in the nginx `location` block pointing to n8n. See the dedicated section above.",{"type":34,"title":96,"body":97},"Maintaining and scaling the instance","For updates, two approaches: Watchtower (automatic image monitoring and restart) or a manual cron job (`docker pull n8nio\u002Fn8n:latest && docker compose up -d`). In both cases, read the release notes before a major update — the breaking changes listed above are representative of the pace of change. Keep your workflow exports up to date in a git repository: this is the fastest backup to restore in case of an incident.","Your VPS for n8n, in minutes","ServOrbit offers Linux VPS with root access, dedicated IPv4 and NVMe SSD — ready to host Docker and n8n without additional configuration. Visit the developers page to choose the configuration suited to your workflows.","Discover ServOrbit VPS","\u002Fsolutions\u002Fdeveloppeurs",[103],{"id":104,"slug":105,"slugs":106,"title":109,"excerpt":110,"readTime":7,"views":15,"isPinned":16,"publishedAt":111,"category":112,"categories":117,"featuredImage":25,"bgImage":26,"posterImage":119,"relatedSolution":120},93,"n8n-vs-node-red-which-self-hosted-automation-tool-to-choose",{"fr":107,"en":105,"ar":108},"n8n-vs-node-red","n8n-مقابل-node-red-أي-أداة-أتمتة-مستضافة-ذاتيا-تختار","n8n vs Node-RED: which self-hosted automation tool to choose?","n8n or Node-RED to automate your workflows on a VPS? Technical comparison, Docker prerequisites and self-hosted deployment guide.","2026-03-19T00:00:00+00:00",{"id":113,"name":114,"slug":115,"color":116,"icon":115},5,"Comparison","comparatif","bg-info\u002F10 text-info",[118],{"id":113,"name":114,"slug":115,"color":116,"icon":115},"\u002Fblog\u002Fcovers\u002Fn8n-vs-node-red-poster.svg",{"categorySlug":29,"appSlug":30},1787581007000]