Guide to migrate n8n to a new VPS (Docker) – Complete & Safe

Migrating n8n from an old VPS to a new VPS may seem simple, but in reality, if you miss a few important steps, you may face serious errors such as losing credentials, webhooks not working, or even the entire workflow disappearing.

This article is written based on real-world experience when migrating n8n in a production environment, ensuring the safest and most complete process.

Guide to migrate n8n to new VPS (Docker) – Complete & Safe
Guide to migrate n8n to a new VPS (Docker) – Complete & Safe

Objective of the migration process

After completing the migration, the new VPS must ensure:

  • Normal n8n login
  • All workflows remain intact
  • Credentials are not faulty (no red color displayed)
  • Webhooks and Cron work stably
  • Execution history is preserved

Components to be migrated (VERY IMPORTANT)

A complete n8n stack includes 4 mandatory parts:

1. Database

  • PostgreSQL / MySQL / SQLite

2. n8n data directory

  • Workflows
  • Credentials
  • Executions

3. Environment variables

  • Especially N8N_ENCRYPTION_KEY

4. Domain & webhook configuration

Note: Missing even one of these four parts can cause serious errors in the entire system.


Step 1: Prepare on old VPS (Source VPS)

1.1. Check if n8n is running

First, check how n8n is currently running:

bash

docker ps
docker compose ps

Identify the following information:

  • Type of database in use
  • Where the volume is mounted (~/.n8n or Docker volume)

1.2. Backup database

With PostgreSQL:

bash

docker exec -t postgres \
  pg_dump -U n8n n8n > n8n.sql

With MySQL:

bash

docker exec -t mysql \
  mysqldump -u n8n -p n8n > n8n.sql

With SQLite:

bash

cp ~/.n8n/database.sqlite n8n.sqlite

1.3. Backup n8n data

If using bind mount:

bash

tar -czvf n8n-data.tar.gz ~/.n8n

If using Docker volume:

bash

docker run --rm \
  -v n8n_data:/data \
  -v $(pwd):/backup \
  alpine tar czvf /backup/n8n-data.tar.gz /data

Important notes: This directory contains all encrypted credentials.

1.4. Save environment variables (.env)

File .env must have the following variables:

env

N8N_ENCRYPTION_KEY=
DB_TYPE=
DB_POSTGRESDB_DATABASE=
DB_POSTGRESDB_USER=
DB_POSTGRESDB_PASSWORD=
N8N_HOST=
WEBHOOK_URL=

⚠️ WARNING: Loss N8N_ENCRYPTION_KEY means losing all credentials!


Step 2: Prepare new VPS (Destination VPS)

2.1. Install Docker & Docker Compose

bash

apt update && apt upgrade -y
apt install docker.io docker-compose-plugin -y
systemctl enable docker --now

2.2. Create project directory

bash

mkdir -p /opt/n8n
cd /opt/n8n

Copy the following files into this directory:

  • docker-compose.yml
  • .env
  • Backup file (n8n.sql, n8n-data.tar.gz)

Step 3: Restore data on new VPS

3.1. Restore n8n data

With bind mount:

bash

tar -xzvf n8n-data.tar.gz -C /

With Docker volume:

bash

docker volume create n8n_data

docker run --rm \
  -v n8n_data:/data \
  -v $(pwd):/backup \
  alpine tar xzvf /backup/n8n-data.tar.gz -C /

3.2. Restore database

PostgreSQL:

bash

docker compose up -d postgres
docker exec -i postgres \
  psql -U n8n n8n < n8n.sql

MySQL:

bash

docker compose up -d mysql
docker exec -i mysql \
  mysql -u n8n -p n8n < n8n.sql

Step 4: Start n8n

Start n8n:

bash

docker compose up -d

Monitor logs to check:

bash

docker compose logs -f n8n

When you see the following log line, n8n has started successfully:

Editor is now accessible via:

Step 5: Fix domain & webhook (THE MOST EASILY FORGOTTEN STEP)

5.1. Update .env file

env

N8N_HOST=n8n.domainmoi.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.domainmoi.com/

Then restart n8n:

bash

docker compose restart n8n

5.2. Test webhook

  1. Open workflow with webhook
  2. Click Test URL
  3. Test by calling with browser or curl

If webhook errors, it's almost certainly due to WEBHOOK_URL not being configured correctly.


Step 6: Post-migration checklist

  • ✅ Successfully logged into n8n
  • ✅ Workflow is still complete
  • ✅ Credentials not showing red
  • ✅ Webhook working normally
  • ✅ Cron workflow running on schedule
  • ✅ Execution history intact

Common errors when migrating n8n

ErrorCauseHow to handle
Credentials errorLost encryption keyUse old key
Webhook returns 404Wrong WEBHOOK_URLSet correct domain
No workflow foundDB not restored yetRe-import SQL
n8n restarts continuouslyWrong DB envCheck again .env
OAuth errorChange domainRe-authorize

Real-world experience

Always stop n8n before backup:

bash

docker compose stop n8n

Some other notes:

  • Production environment should use PostgreSQL instead of SQLite
  • Save file .env to password manager to avoid loss
  • Snapshot VPS before migrate to be able to rollback if needed
  • If using queue mode, remember to migrate Redis as well

Conclusion

Migrating n8n to a new VPS will be completely safe if you ensure all 4 pillars:

  1. Database – Contains all workflows and executions
  2. n8n data – Credentials and configuration
  3. Encryption key – To decrypt credentials
  4. Webhook – Ensure domain and URL are correct

If you're having trouble during the migration process or need more support, don't hesitate to leave a comment below. Let me know:

  • Are you using PostgreSQL or MySQL?
  • Single n8n or queue mode?
  • Are you using reverse proxy (Nginx / Traefik / Cloudflare)?

I will support and provide specific commands suitable for your stack!

DPS.MEDIA