How to Self-Host n8n on a $5 VPS: Complete Setup Guide (2026)
n8n’s self-hosted option is the best value in automation. Unlimited workflows, unlimited executions, and it costs $5/month instead of $50-200/month for cloud plans.
But setting it up yourself means Docker, SSL, and server maintenance. This guide walks you through the entire process — no DevOps experience needed.
What you’ll have by the end:
- n8n running on your own VPS
- HTTPS with automatic SSL renewal
- Automatic backups to S3-compatible storage
- Email notifications for errors
- A setup that costs $5/month forever
Step 0: Pick a VPS Provider
Any Linux VPS works. Here are the best options at $5/month:
| Provider | Plan | RAM | CPU | Price |
|---|---|---|---|---|
| Hetzner | CX22 | 4 GB | 2 vCPU | €3.99/mo |
| DigitalOcean | Basic | 1 GB | 1 vCPU | $6/mo |
| Vultr | Regular | 1 GB | 1 vCPU | $6/mo |
| Linode | Nanode | 1 GB | 1 vCPU | $5/mo |
We recommend Hetzner CX22 — it’s the cheapest and has 4 GB RAM, which is plenty for n8n plus a few side services.
Choose Ubuntu 24.04 LTS as the operating system.
Step 1: Initial Server Setup
SSH into your server:
ssh root@your-server-ip
Update packages and create a non-root user:
apt update && apt upgrade -y
adduser n8n
usermod -aG sudo n8n
su - n8n
Step 2: Install Docker
n8n runs best in Docker. Install Docker Engine:
# Add Docker's official GPG key
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add your user to docker group (no sudo needed)
sudo usermod -aG docker $USER
newgrp docker
Verify it works:
docker run hello-world
Step 3: Create the n8n Docker Compose Setup
Create a directory and docker-compose.yml:
mkdir -p ~/n8n && cd ~/n8n
nano docker-compose.yml
Paste this configuration:
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST=n8n.yourdomain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://n8n.yourdomain.com
- N8N_DIAGNOSTICS_ENABLED=false
- DB_TYPE=sqlite
- N8N_USER_FOLDER=/home/node/.n8n
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
volumes:
n8n_data:
Replace
n8n.yourdomain.comwith your actual subdomain. You’ll set up DNS in the next step.
Step 4: Set Up DNS
Go to your DNS provider (Cloudflare, Namecheap, etc.) and add an A record:
- Type: A
- Name:
n8n(or whatever subdomain you want) - Value: your VPS IP address
- TTL: Auto
If using Cloudflare, turn off the orange cloud (proxy) for now. You’ll re-enable it after SSL is set up.
Step 5: Install Nginx and SSL with Certbot
We’ll use Nginx as a reverse proxy and Certbot for free SSL:
sudo apt install -y nginx certbot python3-certbot-nginx
Create an Nginx config for n8n:
sudo nano /etc/nginx/sites-available/n8n
server {
server_name n8n.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# WebSocket support (needed for n8n editor)
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
Enable the site and get SSL:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Get SSL certificate
sudo certbot --nginx -d n8n.yourdomain.com
Certbot will ask for an email (for renewal notices) and whether to redirect HTTP to HTTPS — choose yes (redirect).
Step 6: Start n8n
cd ~/n8n
docker compose up -d
Wait 10 seconds, then visit https://n8n.yourdomain.com. You should see the n8n setup screen!
Create your admin account and you’re in.
Step 7: Automatic Backups
Backups are critical. Here’s a simple daily backup script:
nano ~/n8n/backup.sh
#!/bin/bash
BACKUP_DIR="/home/n8n/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
# Stop n8n briefly for consistent backup
cd /home/n8n/n8n
docker compose stop n8n
# Backup the data volume
docker run --rm -v n8n_n8n_data:/data -v $BACKUP_DIR:/backup alpine \
tar czf /backup/n8n_backup_$TIMESTAMP.tar.gz -C /data .
# Start n8n again
docker compose start n8n
# Remove old backups
find $BACKUP_DIR -name "n8n_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: n8n_backup_$TIMESTAMP.tar.gz"
Make it executable and add to cron:
chmod +x ~/n8n/backup.sh
(crontab -l 2>/dev/null; echo "0 3 * * * /home/n8n/n8n/backup.sh >> /home/n8n/n8n/backup.log 2>&1") | crontab -
This runs every day at 3 AM, keeps 7 days of backups. For off-server backups, add a step to upload to S3 or rsync to another server.
Step 8: Monitoring and Updates
Automatic Updates
nano ~/n8n/update.sh
#!/bin/bash
cd /home/n8n/n8n
docker compose pull n8n
docker compose up -d
docker image prune -f
chmod +x ~/n8n/update.sh
# Run manually when you want to update
# Or add to crontab for weekly updates
Uptime Monitoring (Free)
Use UptimeRobot (free for 50 monitors) to ping your n8n instance every 5 minutes. If it goes down, you get an email.
Add https://n8n.yourdomain.com/healthz as the monitor URL — n8n returns 200 OK on this endpoint.
Step 9: Security Hardening
A few quick security steps:
# Enable UFW firewall
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
# Fail2ban for SSH protection
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
# Set up unattended security updates
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
For Cloudflare users: once SSL is working, re-enable the orange cloud (proxy) on your DNS record. This hides your server IP and adds DDoS protection.
Troubleshooting
”502 Bad Gateway” after setup
→ n8n container isn’t running. Check with docker compose logs n8n.
Webhooks don’t work
→ Make sure WEBHOOK_URL in docker-compose.yml is set to https://n8n.yourdomain.com.
Can’t connect via HTTPS
→ Check sudo certbot certificates to verify SSL is issued. Check sudo nginx -t for config errors.
Server runs out of memory
→ n8n with SQLite is light, but if you have 50+ active workflows, consider switching to PostgreSQL. Add a PostgreSQL service to docker-compose.yml.
Cost Breakdown
| Item | Monthly Cost |
|---|---|
| Hetzner CX22 VPS | €3.99 (~$4.30) |
| Domain (if you want a separate one) | ~$1 |
| Backups (S3-compatible storage) | ~$0.50 |
| Total | ~$5/month |
Compare that to n8n Cloud Pro at €50/month ($54) — you save $590/year.
What’s Next?
Now that n8n is running, check out our tutorials:
- Build a Client Onboarding Automation with n8n
- n8n vs Make: Cost Comparison
- Best No-Code Automation Tools 2026
Questions about the setup? Email us. If you’re stuck, the n8n community forum is excellent for troubleshooting.