Deployment guide

n8n 3.0: migrating from npm to Docker before October 2026

Deploy on a VPS Cloud →

Automation8 min read

n8n 3.0: migrating from npm to Docker before October 2026

n8n 3.0 is scheduled for October 2026 and introduces a structural change: support for npm and npx installations is removed. Only Docker will be distributed. If your instance still runs with `npx n8n` or a global npm package, migration must happen before that date — not because it stops working today, but because a planned migration is always safer than an emergency migration on a Sunday night.

What changes with n8n 3.0 and why act now

The official n8n 3.0 breaking changes documentation is unambiguous: "Self-hosted n8n will require a Docker-based deployment. n8n 3.0 will no longer support installations run using npm or npx n8n." This is not a gradual deprecation warning — it is a hard deadline. In October 2026, any instance launched via npx n8n or a global npm package will no longer be updatable. It will be frozen on the last 2.x version, without security patches.

Risks of delaying migration to October

  • Migration under pressure — migrating in an emergency while critical automations are running exposes you to configuration errors that are difficult to diagnose.
  • SQLite data loss — GitHub issue #22341 documents cases where Docker containers updated without precautions caused a database regression: workflows and executions "go back in time" to the state of an old backup.
  • No security patches — an npm instance frozen at 2.x no longer receives security patches or stability fixes published for the 3.x branch.
  • Growing incompatibility — integrations, community nodes and webhooks rely on APIs that evolve; staying on a dead version creates growing incompatibility debt.
  • Unpredictable duration — a well-prepared migration takes one hour; an improvised migration can take a full day, during which your workflows are stopped.

Prerequisites before starting

This procedure targets an existing n8n instance in production. If you are starting from scratch, refer to the dedicated article on installing n8n on a VPS.

What you need

  • VPS with root access — Ubuntu 22.04 or Debian 12 recommended, minimum 2 vCPU and 2 GB RAM for n8n alone, 4 GB if you add PostgreSQL on the same host.
  • Docker Engine and Docker Compose v2 — verify with docker --version and docker compose version (no-hyphen syntax, v2 plugin).
  • PostgreSQL recommended — n8n supports both SQLite and PostgreSQL, but SQLite on Docker carries data loss risks during poorly managed updates (cf. issue #22341); PostgreSQL is the target for any instance that matters.
  • Access to the current npm instance — the migration requires exporting workflows via the REST API before stopping the old instance.
  • A domain name and a TLS certificate — n8n in production is not exposed over raw HTTP; Nginx acts as a reverse proxy with Let's Encrypt.
  • A planned maintenance window — even a short one avoids losing in-progress executions.

Detect your current launch mode

Before anything else, identify precisely how your n8n instance is launched. The command to use depends on the supervision mode.

Detect, export, deploy and validate

01

Identify the n8n process

Look for the running executable: which n8n shows the path if n8n is installed globally via npm. Then check if a system service supervises it: systemctl status n8n or systemctl status n8n.service. If no systemd service exists, look for an active process: ps aux | grep n8n. A result containing node .../n8n/bin/n8n or npx n8n confirms an npm installation.

02

Locate the configuration file and database

The default data directory is ~/.n8n/. Check its contents: ls -la ~/.n8n/. The database.sqlite file indicates an SQLite database. Note the full path — you will need it for the export. If the N8N_USER_FOLDER variable is set in the process environment (cat /proc/$(pgrep -f n8n)/environ | tr '\0' '\n' | grep N8N), that path takes precedence.

03

Export all your workflows via the REST API

The n8n REST API allows exporting workflows as JSON. First retrieve an API key from the interface (Settings → API → Create API Key), then export: curl -s -H 'X-N8N-API-KEY: YOUR_KEY' http://localhost:5678/api/v1/workflows | python3 -m json.tool > workflows-export-$(date +%Y%m%d).json. Verify the file contains your workflows: python3 -c "import json; d=json.load(open('workflows-export-*.json')); print(len(d['data']), 'workflows exported')". Keep this file safe before any operation.

04

Cleanly stop the npm instance

If supervised by systemd: systemctl stop n8n && systemctl disable n8n. If launched manually in a terminal or via a startup script, identify the PID (pgrep -f n8n) then kill -SIGTERM <PID>. Wait a few seconds for n8n to finish in-progress executions before forcing the stop. Once stopped, back up ~/.n8n/database.sqlite if you want to preserve execution history.

05

Create the docker-compose.yml file with PostgreSQL

Create a dedicated directory: mkdir -p /opt/n8n && cd /opt/n8n. Then create the docker-compose.yml file with the following content — adapt passwords and domain:

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: CHANGE_THIS_PASSWORD
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:2.38.4
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: CHANGE_THIS_PASSWORD
      N8N_HOST: your-domain.com
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://your-domain.com/
      N8N_BASIC_AUTH_ACTIVE: "true"
      N8N_BASIC_AUTH_USER: admin
      N8N_BASIC_AUTH_PASSWORD: CHANGE_THIS_AUTH_PASSWORD
    volumes:
      - n8n_data:/home/node/.n8n
    ports:
      - "127.0.0.1:5678:5678"

volumes:
  postgres_data:
  n8n_data:

Note: the version is pinned to 2.38.4 (stable as of 2026-09-09). Never use :latest — see the tip below.

06

Start the stack and import workflows

Start the stack: docker compose up -d. Wait for both containers to be healthy: docker compose ps. Once n8n is accessible at http://127.0.0.1:5678, import your workflows via the API: curl -s -X POST -H 'X-N8N-API-KEY: YOUR_NEW_KEY' -H 'Content-Type: application/json' -d @workflows-export-YYYYMMDD.json http://127.0.0.1:5678/api/v1/workflows. Verify in the interface that your workflows, connections and credentials are present.

07

Configure Nginx as a reverse proxy with TLS

Install Nginx and Certbot if not already done: apt install nginx certbot python3-certbot-nginx -y. Create the Nginx configuration in /etc/nginx/sites-available/n8n with a proxy_pass to http://127.0.0.1:5678, including WebSocket upgrade headers and a 300s read timeout. Enable the site and obtain the certificate: ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/ && certbot --nginx -d your-domain.com.

08

Validate that the migration succeeded

Perform these checks in order: 1) access https://your-domain.com — the login page appears without a TLS warning; 2) log in and verify your workflows are present and active; 3) manually trigger a simple workflow to validate end-to-end execution; 4) check webhooks: if third-party services point to your old URL or old port, update them in n8n (Settings → Webhooks); 5) let it run for 24 hours and review the logs: docker compose logs n8n --since 24h | grep -i error.

Always pin a version, never :latest

Using n8nio/n8n:latest in your docker-compose.yml exposes you to uncontrolled automatic updates during a docker compose pull. On an SQLite database, a major version jump without prior migration can trigger the scenario described in issue #22341: data appears present in the volume but the database reverts to an earlier state. Always pin a specific version (n8nio/n8n:2.38.4) and plan your upgrades. To move to a new version, read the release notes first, then: docker compose pull && docker compose up -d.

Troubleshooting: common issues after migration

Here are the most frequently encountered problems during this transition.

Issues and solutions

  • Empty workflows after import — verify that the exported JSON format matches what the import API expects; some n8n versions export an { data: [] } object, others a direct array. Adapt the curl command accordingly.
  • Webhooks no longer responding — the WEBHOOK_URL variable must match exactly the public URL of your instance (with https://). Incorrect setup generates wrong webhook URLs in the interface.
  • Inaccessible credentials — credentials are encrypted with the N8N_ENCRYPTION_KEY. If you do not set it explicitly and start from a new n8n_data volume, old credentials are lost. Retrieve the key from ~/.n8n/.n8n_encryption_key on the npm instance and set it as an environment variable.
  • SQLite database regression (issue #22341) — if you chose to keep SQLite temporarily, ensure the Docker volume is mounted persistently and that you are not using --rm or an aggressive restart policy. Migration to PostgreSQL remains the definitive resolution.
  • ECONNREFUSED error on PostgreSQL — the depends_on.postgres.condition: service_healthy condition and the pg_isready healthcheck ensure n8n waits for PostgreSQL to be ready. Without this condition, n8n starts before PostgreSQL and fails.

A migration to do now, not in October

The stable version of n8n at the time of this article is 2.38.4. You have several weeks to conduct this migration properly: cleanly export your workflows, test the Docker stack on a test server, then switch production with a real rollback plan. In October, when n8n 3.0 is available, you will only need to bump the version number in your docker-compose.yml — a five-minute step. The difference between five minutes and a stressful day starts now.

A VPS ready for Docker and n8n

ServOrbit offers VPS with root access, dedicated IPv4 and OS choice. Launch your n8n stack in minutes with our Docker template.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab