Artur
Artur
Founder

How to Back Up and Restore n8n (Docker + Postgres)

April 23, 2026

n8n-backupn8n-dockern8n-postgresself-hosted-automationdisaster-recovery

Skip your encryption key backup and every credential becomes unreadable after a restore. This is the most common mistake self-hosters make - and it's unrecoverable.

Here's everything you need to back up, automate, and restore your n8n instance running on Docker with PostgreSQL.

What You Actually Need to Back Up

Three things matter. Miss any one and your restore fails:

PostgreSQL database - Contains all workflows, credentials (encrypted), execution history, and settings. This is your primary backup target.

N8N_ENCRYPTION_KEY - The key that encrypts all credentials stored in your database. Without the exact same key, restored credentials are garbage. Find it in your .env file or docker-compose environment variables.

n8n_data volume - Contains custom nodes, local file storage, and configuration at /home/node/.n8n. Secondary priority but still important.

What you can skip: execution logs older than your retention period, temporary files, container images (just pull fresh).

Backing Up PostgreSQL with pg_dump

Unlike SQLite, PostgreSQL supports hot backups - no need to stop n8n first [4].

Run this from your Docker host:

docker exec n8n-postgres pg_dump -U n8n -d n8n > n8n_backup_$(date +%Y-%m-%d).sql

Replace n8n-postgres with your actual container name. Check with docker ps.

For compressed backups (recommended for larger instances):

docker exec n8n-postgres pg_dump -U n8n -d n8n | gzip > n8n_backup_$(date +%Y-%m-%d).sql.gz

Store backups outside your server. A backup on the same disk as your data isn't a backup - it's a copy waiting to die with the original [3].

Backing Up the n8n_data Volume

First, find your volume name:

docker volume ls | grep n8n

Then create a compressed archive:

docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine tar czf /backup/n8n_data_$(date +%Y-%m-%d).tar.gz -C /data .

This mounts the volume into a temporary Alpine container and tars the contents. The backup lands in your current directory [2].

Saving Your Encryption Key

Your encryption key lives in one of these places:

  • N8N_ENCRYPTION_KEY environment variable in docker-compose.yml

  • .env file in your n8n directory

  • Passed directly via docker run -e

Copy it somewhere safe. Password manager, separate encrypted file, whatever - just not on the same server as n8n.

"Use the same N8N_ENCRYPTION_KEY as your old instance. This is critical: a different key means all credentials become unreadable." - Serverspace.io migration guide [4]

Automated Nightly Backups with Cron

Create a backup script at /opt/n8n-backup/backup.sh:

#!/bin/bash
BACKUP_DIR="/opt/n8n-backup/backups"
DATE=$(date +%Y-%m-%d)
RETENTION_DAYS=14

# Create backup directory
mkdir -p $BACKUP_DIR

# Backup PostgreSQL
docker exec n8n-postgres pg_dump -U n8n -d n8n | gzip > $BACKUP_DIR/n8n_db_$DATE.sql.gz

# Backup n8n_data volume
docker run --rm -v n8n_data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/n8n_data_$DATE.tar.gz -C /data .

# Delete backups older than retention period
find $BACKUP_DIR -type f -mtime +$RETENTION_DAYS -delete

# Optional: sync to remote storage
# rsync -avz $BACKUP_DIR/ user@remote-server:/backups/n8n/

Make it executable and schedule it:

chmod +x /opt/n8n-backup/backup.sh
crontab -e

Add this line for 2 AM nightly backups:

0 2 * * * /opt/n8n-backup/backup.sh >> /var/log/n8n-backup.log 2>&1

The 14-day retention keeps enough history without eating disk space. Adjust based on your needs [2][5].

Restoring n8n from Backup

Full restore procedure when setting up a new server or recovering from disaster:

Step 1: Set up fresh containers

Deploy your docker-compose.yml with the same configuration. Critical: use the identical N8N_ENCRYPTION_KEY from your backup.

environment:
  - N8N_ENCRYPTION_KEY=your-original-key-here

Step 2: Restore PostgreSQL

Stop n8n but keep PostgreSQL running:

docker stop n8n

For uncompressed backups:

cat n8n_backup_2026-04-22.sql | docker exec -i n8n-postgres psql -U n8n -d n8n

For gzipped backups:

gunzip -c n8n_backup_2026-04-22.sql.gz | docker exec -i n8n-postgres psql -U n8n -d n8n

If restoring to a fresh database, you may need to drop and recreate first:

docker exec n8n-postgres psql -U n8n -c "DROP DATABASE n8n; CREATE DATABASE n8n;"

Step 3: Restore n8n_data volume

docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine sh -c "rm -rf /data/* && tar xzf /backup/n8n_data_2026-04-22.tar.gz -C /data"

Step 4: Start n8n and verify

docker start n8n

Check your workflows load. Test one credential-dependent workflow to confirm encryption key matches [2][5][7].

What Goes Wrong (And How to Avoid It)

Wrong encryption key - All credentials show as invalid. No fix except re-entering every credential manually. Prevention: triple-check your key backup.

Assuming SQLite migration covers Postgres - Different databases, different backup methods. If you migrated from SQLite to Postgres, your old SQLite backups are useless [4].

Untested backups - Community guides suggest untested backups fail restoration often. Run a test restore quarterly on a separate environment [2][3].

No off-site storage - Your server dies, your backups die with it. Use rsync, S3, or any remote storage. Add it to your backup script [3].

Forgetting volume mounts - Check your actual volume name with docker inspect n8n | grep -A 5 Mounts. Container names and volume names don't always match [6].

Testing Your Restore Process

A backup you've never tested is a backup that doesn't work.

Quarterly test procedure:

  1. Spin up a test environment (separate VM or different Docker network)
  2. Deploy fresh n8n with your backed-up encryption key
  3. Restore database and volume backups
  4. Verify workflows appear correctly
  5. Execute one workflow that uses credentials
  6. Document any issues

Takes an hour. Saves your business when disaster actually hits.

FAQ

Can I back up n8n while workflows are running?

Yes. PostgreSQL's pg_dump creates consistent snapshots without stopping the database. Your workflows keep running during backup [4].

What happens if I lose my encryption key?

All credentials become permanently unreadable. You'll need to delete and re-create every credential manually. There's no recovery option. Back up that key [4][5].

How much storage do n8n backups need?

Depends on execution history retention. A typical instance with 50 workflows and 30-day execution history runs 100-500MB compressed. Monitor your backup directory size monthly.

Should I back up n8n credentials separately?

No need. Credentials are stored encrypted in PostgreSQL. Backing up the database and encryption key together covers credentials completely.

Can I restore to a different server?

Yes. Deploy the same docker-compose setup with identical environment variables (especially N8N_ENCRYPTION_KEY), then follow the standard restore procedure. Works across different hosts and cloud providers [2][5].

How do I know my backup succeeded?

Check file sizes (empty files indicate failures), verify dates match, and periodically test restores. Add error checking to your backup script that alerts on failure.


Setting up proper backups takes an afternoon. Recovering without them takes weeks - and some data never comes back.

If you'd rather have experts handle your n8n infrastructure - backups, updates, scaling - n8n Logic provides managed automation services that handle the ops work while you focus on building workflows.


How to Back Up and Restore n8n (Docker + Postgres) | n8nlogic