n8n is a powerful workflow automation tool that you can run on your own server. Unlike Zapier or Make, self-hosted n8n has no per-execution fees - pay only for your server.
I've deployed n8n for multiple clients and use it for my own automation needs. In my experience, self-hosting is worth the initial setup effort. This guide walks you through setting up n8n from download to production-ready deployment.
Why Self-Host n8n?
Before we start the installation, here's why you might choose self-hosted over n8n Cloud:
Cost savings: No per-execution fees. Run 100,000 workflows per month for the cost of a $20/month server.
Data privacy: Your data stays on your server. Critical for healthcare, finance, or any sensitive data.
Full control: Customize everything. No vendor limitations.
No vendor lock-in: Your workflows are yours. Export and migrate anytime.
The trade-off: You manage the infrastructure. I found it's surprisingly low-maintenance once set up properly - this guide shows you how.
What Do You Need Before Installing n8n?
Before you download and install n8n, you'll need:
- A server (VPS) with at least 2GB RAM
- Ubuntu 22.04 or newer (this guide uses Ubuntu)
- A domain name pointed to your server
- Basic command line knowledge
- SSH access to your server
Recommended providers:
- DigitalOcean ($12-24/month)
- Hetzner ($5-10/month) - Best value
- Linode ($12-24/month)
- AWS Lightsail ($10-20/month)
Quick Start: n8n Download and Setup
For those who want to get running fast, here's the minimal setup:
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Run n8n
docker run -d \
--name n8n \
--restart always \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
n8nio/n8n
Access n8n at http://your-server-ip:5678
This works but isn't production-ready. Keep reading for a proper setup.
Step 1: Prepare Your Server
Update System
sudo apt update && sudo apt upgrade -y
Install Docker
# Download and install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to docker group
sudo usermod -aG docker $USER
# Log out and back in, then verify
docker --version
Install Docker Compose
sudo apt install docker-compose-plugin -y
# Verify
docker compose version
Configure Firewall
sudo ufw allow 22 # SSH
sudo ufw allow 80 # HTTP
sudo ufw allow 443 # HTTPS
sudo ufw enable
Step 2: Set Up n8n with Docker Compose
Create a directory for n8n:
mkdir -p ~/n8n && cd ~/n8n
Create the Docker Compose file:
nano docker-compose.yml
Paste this configuration:
version: '3.8'
services:
n8n:
image: n8nio/n8n
container_name: n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=${TIMEZONE}
# Security
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
# Database (optional - SQLite by default)
# - DB_TYPE=postgresdb
# - DB_POSTGRESDB_HOST=postgres
# - DB_POSTGRESDB_DATABASE=n8n
# - DB_POSTGRESDB_USER=n8n
# - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
networks:
- n8n-network
networks:
n8n-network:
volumes:
n8n_data:
Create the environment file:
nano .env
Add your configuration:
N8N_HOST=n8n.yourdomain.com
TIMEZONE=America/New_York
N8N_USER=admin
N8N_PASSWORD=your-secure-password-here
Important: Use a strong password. This protects your entire automation system.
Step 3: Set Up SSL with Caddy
n8n needs HTTPS for webhooks to work reliably. We'll use Caddy as a reverse proxy - it handles SSL certificates automatically.
Add Caddy to your docker-compose.yml:
version: '3.8'
services:
caddy:
image: caddy:2
container_name: caddy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- n8n-network
n8n:
image: n8nio/n8n
container_name: n8n
restart: always
# Remove ports - Caddy handles external access
# ports:
# - "5678:5678"
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=${TIMEZONE}
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
networks:
- n8n-network
networks:
n8n-network:
volumes:
n8n_data:
caddy_data:
caddy_config:
Create the Caddyfile:
nano Caddyfile
Add:
n8n.yourdomain.com {
reverse_proxy n8n:5678
}
Replace n8n.yourdomain.com with your actual domain.
Step 4: Start n8n
docker compose up -d
Check that everything is running:
docker compose ps
You should see both caddy and n8n with status "Up".
Access n8n at https://n8n.yourdomain.com
Step 5: Configure n8n
Initial Setup
On first access:
- Log in with the credentials from your .env file
- Create your owner account (this is different from basic auth)
- Set up your first workflow
Essential Settings
Go to Settings → Personal:
- Set your timezone correctly
- Configure your name and email
Go to Settings → Community nodes (optional):
- Enable community nodes for additional integrations
Security Hardening
Add these environment variables for additional security:
environment:
# ... existing vars ...
- N8N_BLOCK_ENV_ACCESS_IN_NODE=true
- N8N_PERSONALIZATION_ENABLED=false
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168 # 7 days in hours
Step 6: Set Up Backups
Your n8n data is stored in Docker volumes. Set up automatic backups:
Create backup script:
nano ~/n8n/backup.sh
Add:
#!/bin/bash
BACKUP_DIR="/home/$USER/n8n-backups"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mkdir -p $BACKUP_DIR
# Export workflows
docker exec n8n n8n export:workflow --all --output=/files/workflows-$DATE.json
# Export credentials (encrypted)
docker exec n8n n8n export:credentials --all --output=/files/credentials-$DATE.json
# Backup the volume
docker run --rm \
-v n8n_n8n_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/n8n-data-$DATE.tar.gz -C /data .
# Move exported files
mv ~/n8n/local-files/workflows-$DATE.json $BACKUP_DIR/
mv ~/n8n/local-files/credentials-$DATE.json $BACKUP_DIR/
# Keep only last 7 backups
ls -tp $BACKUP_DIR/*.tar.gz | tail -n +8 | xargs -I {} rm -- {}
ls -tp $BACKUP_DIR/workflows-*.json | tail -n +8 | xargs -I {} rm -- {}
ls -tp $BACKUP_DIR/credentials-*.json | tail -n +8 | xargs -I {} rm -- {}
echo "Backup completed: $DATE"
Make it executable and schedule:
chmod +x ~/n8n/backup.sh
# Add to crontab - daily at 2 AM
(crontab -l 2>/dev/null; echo "0 2 * * * /home/$USER/n8n/backup.sh") | crontab -
Step 7: Set Up Monitoring
Basic Health Check
Add a simple health check script:
nano ~/n8n/health-check.sh
#!/bin/bash
HEALTH=$(curl -s -o /dev/null -w "%{http_code}" https://n8n.yourdomain.com/healthz)
if [ "$HEALTH" != "200" ]; then
echo "n8n is down! Status: $HEALTH" | mail -s "n8n Alert" your@email.com
# Or send to Slack/Discord webhook
fi
Execution Monitoring
Create a workflow in n8n that:
- Runs on schedule (daily)
- Queries the n8n API for failed executions
- Sends alert if failures exceed threshold
Production Configuration
Using PostgreSQL Instead of SQLite
For production with high volume, use PostgreSQL:
services:
postgres:
image: postgres:15
container_name: n8n-postgres
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n-network
n8n:
# ... existing config ...
environment:
# ... existing vars ...
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
depends_on:
- postgres
Add to .env:
DB_PASSWORD=your-database-password
Queue Mode for High Volume
For many concurrent executions, enable queue mode with Redis:
services:
redis:
image: redis:7
container_name: n8n-redis
restart: always
networks:
- n8n-network
n8n:
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_HEALTH_CHECK_ACTIVE=true
Resource Limits
Add resource limits to prevent runaway workflows:
n8n:
# ... existing config ...
deploy:
resources:
limits:
memory: 2G
cpus: '2'
reservations:
memory: 512M
How Do You Update n8n?
Check Current Version
docker exec n8n n8n --version
Update Process
cd ~/n8n
# Pull latest image
docker compose pull
# Restart with new image
docker compose up -d
# Check logs for issues
docker compose logs -f n8n
Rollback if Needed
# Stop current version
docker compose down
# Use specific version
# Edit docker-compose.yml: image: n8nio/n8n:0.236.0
docker compose up -d
Troubleshooting
n8n Won't Start
Check logs:
docker compose logs n8n
Common issues:
- Port already in use: Change the port in docker-compose.yml
- Permission issues: Check volume permissions
- Memory issues: Increase server RAM or add swap
Webhooks Not Working
Verify:
- SSL is working:
curl -I https://n8n.yourdomain.com - WEBHOOK_URL is correct in .env
- Firewall allows 443
Executions Failing
Check:
- Execution logs in n8n UI
- Docker logs:
docker compose logs -f n8n - Resource usage:
docker stats
Database Connection Issues
For PostgreSQL:
# Check if postgres is running
docker compose ps postgres
# Check connection
docker exec n8n-postgres psql -U n8n -d n8n -c "SELECT 1;"
Where Do You Download n8n?
Official Sources
- Docker Hub:
docker pull n8nio/n8n - GitHub: https://github.com/n8n-io/n8n
- npm:
npm install -g n8n(not recommended for production)
Version Pinning
For production, pin to specific versions:
image: n8nio/n8n:1.20.0
Check releases: https://github.com/n8n-io/n8n/releases
Next Steps
Now that n8n is running:
- Create your first workflow: Start with something simple like a webhook-to-Slack notification
- Import community workflows: Many templates available on n8n.io
- Set up error notifications: Create a workflow that alerts on execution failures
- Document your setup: Keep notes for future maintenance
Related resources:
- n8n automation examples - Practical workflows to build
- Make vs Zapier - If you're considering alternatives
- Workflow automation services - Professional help
Summary
Self-hosted n8n setup involves:
- Server with Docker
- Docker Compose configuration
- SSL via Caddy reverse proxy
- Backup automation
- Monitoring setup
- Regular updates
Total setup time: 30-60 minutes for a production-ready deployment.
The ongoing maintenance is minimal - occasional updates and monitoring. The cost savings compared to per-execution pricing make self-hosting worthwhile for any serious automation use.
Frequently Asked Questions
How do you install n8n on a server?
The recommended method is Docker Compose: install Docker on a VPS, create a docker-compose.yml file defining the n8n service, add a Caddy reverse proxy for SSL, then run docker compose up -d. A production-ready deployment takes 30-60 minutes from start to finish.
What are the system requirements for self-hosted n8n?
A small VPS with at least 2GB of RAM running Ubuntu 22.04 or newer is enough for most setups. You also need a domain name pointed at the server and SSH access. For high-volume use, increase RAM and switch from SQLite to PostgreSQL.
How much does it cost to self-host n8n?
n8n itself is free and open-source. The only cost is the server, which runs roughly $5-24 per month depending on the provider. Hetzner is the best value at $5-10 per month; DigitalOcean and Linode sit higher. There are no per-execution fees.
Is self-hosted n8n secure?
It can be, with the right setup. Enable basic authentication, run behind HTTPS via a reverse proxy, set N8N_BLOCK_ENV_ACCESS_IN_NODE=true, and keep n8n updated for security patches. Regular backups of the data volume protect against data loss.
Should you use SQLite or PostgreSQL with n8n?
SQLite is fine for light use and is the default - no extra setup needed. Switch to PostgreSQL for production with high execution volume, where SQLite can become a bottleneck. PostgreSQL also handles concurrent access better when running n8n in queue mode.
How do you back up a self-hosted n8n instance?
Back up the Docker data volume at /home/node/.n8n and export workflows and credentials with the n8n export commands. A simple cron job running daily, keeping the last seven backups, covers most needs. Store backups off the server for safety.
Need help with n8n setup or building complex workflows? Check out my n8n automation services or let's talk about your automation needs.