N8N Cloud is convenient. But for businesses that handle sensitive customer data, run high workflow volumes, or simply want full control over their automation stack, self-hosting is the right call. A $10 VPS running Docker can handle hundreds of workflows per day without hitting any execution caps.
This guide walks you through the complete setup: from a fresh Linux server to a production-ready N8N instance with HTTPS, persistent storage, and automatic restarts. No experience with Docker required, just a basic comfort with the command line.
What we cover: Docker and Docker Compose installation, N8N container setup, environment variable configuration, data persistence with volumes, HTTPS via Nginx reverse proxy, backups, and update procedure. Estimated setup time: 25 to 40 minutes.
Why Self-Host N8N?
The case for self-hosting is straightforward for most SMBs running serious automation workloads. N8N Cloud charges by execution and has monthly limits. On a self-hosted instance, you run as many executions as your server can handle, with no per-workflow or per-execution fee.
Three situations where self-hosting clearly wins:
- Data compliance: If workflows process personal data (customer records, financial data, HR data), keeping execution logs on your own infrastructure avoids third-party data handling concerns.
- High volume: Businesses running 10,000+ executions per month will spend significantly more on cloud plans than on a $10 VPS.
- Custom nodes: Self-hosted N8N lets you install community nodes and custom integrations that are not available on N8N Cloud.
If you are just getting started with N8N and want to understand the workflow basics first, read our beginner's guide to building your first N8N workflow before continuing here.
What You Need Before You Start
You need three things:
- A Linux VPS (Ubuntu 22.04 LTS recommended). DigitalOcean, Hetzner, Vultr, and Linode all work. 2 vCPU, 4 GB RAM is a solid starting spec.
- A domain name pointed to your server's IP. You need this for HTTPS. Use an A record:
n8n.yourdomain.com → your.server.ip. - SSH access to the server with a non-root sudo user.
Self-Hosted vs Cloud: Cost and Feature Comparison
Before committing, here is an honest side-by-side comparison:
| Factor | N8N Cloud (Starter) | Self-Hosted (Docker / VPS) |
|---|---|---|
| Monthly cost | $20 (2,500 executions/month) | $5 to $20 (unlimited executions) |
| Setup time | 2 minutes | 25 to 40 minutes |
| Maintenance burden | None (managed) | Low (monthly Docker updates) |
| Execution limits | Yes (varies by plan) | None (server-bound only) |
| Community nodes | Limited | Full access |
| Data residency control | No | Yes (your server, your region) |
| Custom SSL / domain | Subdomain only | Any domain |
| Backups | Managed by N8N | Your responsibility (easy to automate) |
Step 1: Install Docker and Docker Compose
SSH into your server and run the following commands. This installs Docker Engine and the Compose plugin from Docker's official repository:
sudo apt update && sudo apt upgrade -y
# Install dependencies
sudo apt install -y ca-certificates curl gnupg
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
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 Engine + Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add your user to the docker group (so you don't need sudo for every command)
sudo usermod -aG docker $USER
newgrp docker
Verify both are working:
docker --version
docker compose version
Step 2: Create the N8N Directory and Docker Compose File
Create a dedicated directory for your N8N setup:
mkdir -p ~/n8n && cd ~/n8n
Create the Docker Compose file. This is the core configuration that defines how N8N runs:
nano docker-compose.yml
Paste in the following. We'll explain each key section below:
version: "3.8"
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=Europe/Paris
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Key settings to understand:
- restart: unless-stopped ensures N8N restarts automatically if the container crashes or the server reboots.
- n8n_data volume persists all workflows, credentials, and execution history between container restarts and upgrades.
- N8N_ENCRYPTION_KEY encrypts stored credentials. Generate a strong random key and never change it after setup.
- N8N_BASIC_AUTH adds password protection to the N8N UI. Required before you set up HTTPS.
Step 3: Configure Environment Variables
Create a .env file in the same directory. This keeps sensitive values out of your Compose file:
nano .env
Fill in your values:
# Your N8N domain
N8N_HOST=n8n.yourdomain.com
# Basic auth credentials for the N8N UI
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=a-very-strong-password-here
# Generate with: openssl rand -hex 32
N8N_ENCRYPTION_KEY=your-64-character-random-hex-key
Generate your encryption key with this one-liner:
openssl rand -hex 32
Copy the output and paste it as the value for N8N_ENCRYPTION_KEY. Store this key somewhere safe. If you lose it, you lose access to all encrypted credentials stored in N8N.
Step 4: Set Up Nginx as a Reverse Proxy with HTTPS
Exposing N8N directly on port 5678 over HTTP is not acceptable for production. You need Nginx to handle HTTPS and proxy traffic to the N8N container.
Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginx
Create an Nginx configuration file for N8N:
sudo nano /etc/nginx/sites-available/n8n
Paste the following (replace n8n.yourdomain.com with your actual domain):
server {
listen 80;
server_name n8n.yourdomain.com;
location / {
proxy_pass http://localhost: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;
chunked_transfer_encoding on;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
Enable the site and obtain an SSL certificate:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Issue the SSL certificate (follow prompts)
sudo certbot --nginx -d n8n.yourdomain.com
Certbot will automatically modify your Nginx config to enable HTTPS and set up certificate auto-renewal. Your N8N instance is now accessible at https://n8n.yourdomain.com.
Step 5: Start N8N
With Nginx configured, start the N8N container:
cd ~/n8n
docker compose up -d
Check that the container is running:
docker compose ps
docker compose logs -f n8n
You should see N8N starting up in the logs. Open https://n8n.yourdomain.com in your browser, enter the basic auth credentials you set, and you will land on the N8N workflow editor.
Step 6: Configure Timezone and Email (Optional but Recommended)
Set the correct timezone so that scheduled triggers fire at the right times. In the .env file, update:
GENERIC_TIMEZONE=America/New_York
For a full list of timezone strings, see the IANA tz database. This is especially important if you use the Schedule trigger node, which we cover in our N8N scheduled triggers tutorial.
If you want N8N to send email alerts on workflow errors, add SMTP settings to .env:
N8N_EMAIL_MODE=smtp
N8N_SMTP_HOST=smtp.yourmailprovider.com
N8N_SMTP_PORT=587
N8N_SMTP_USER=your@email.com
N8N_SMTP_PASS=your-smtp-password
N8N_SMTP_SENDER=n8n@yourdomain.com
Restart N8N to apply changes:
docker compose down && docker compose up -d
Step 7: Set Up Backups
All N8N data (workflows, credentials, execution history) lives in the n8n_data Docker volume. Backing it up is a 30-second cron job.
Create a backup script:
nano ~/n8n/backup.sh
#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR=~/n8n-backups
mkdir -p $BACKUP_DIR
# Stop N8N (prevents partial writes)
docker compose -f ~/n8n/docker-compose.yml stop n8n
# Archive the volume data
docker run --rm \
-v n8n_n8n_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/n8n-backup-$DATE.tar.gz -C /data .
# Restart N8N
docker compose -f ~/n8n/docker-compose.yml start n8n
# Remove backups older than 30 days
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
echo "Backup complete: n8n-backup-$DATE.tar.gz"
chmod +x ~/n8n/backup.sh
Schedule it daily at 2 AM with cron:
crontab -e
# Add this line:
0 2 * * * /home/youruser/n8n/backup.sh >> /home/youruser/n8n/backup.log 2>&1
For critical automations, also copy backups off-server to S3 or a remote location. Backups on the same server as the application are not disaster-recovery backups.
Step 8: Update N8N
Keeping N8N updated is important for security and new features. The update process with Docker Compose is two commands:
cd ~/n8n
docker compose pull
docker compose up -d
Docker will pull the latest n8n:latest image and restart the container. Your workflows and credentials remain intact because they are stored in the persistent volume, not inside the container.
Before updating major versions (e.g., N8N 1.x to 2.x), always run a manual backup first and check the N8N release notes for breaking changes.
Common Self-Hosting Issues and Fixes
Webhooks not receiving requests
Check that WEBHOOK_URL in your .env matches your public domain exactly, including the trailing slash. Also verify your server firewall allows inbound traffic on ports 80 and 443.
Credentials not saving after restart
This almost always means the n8n_data volume is not mounted correctly, or the N8N_ENCRYPTION_KEY changed between restarts. The key must remain identical for the container lifetime.
N8N UI slow or unresponsive
The container needs more RAM. Upgrade to a 4 GB RAM server if you see memory pressure. You can also limit execution history retention in N8N settings to reduce database size. For advanced error handling patterns in workflows themselves, see our N8N error handling guide.
SSL certificate not renewing
Certbot sets up a systemd timer for auto-renewal. Check its status with sudo systemctl status certbot.timer. Test renewal manually with sudo certbot renew --dry-run.
Connecting Your Self-Hosted N8N to Business Systems
Once N8N is running, the setup process for nodes is identical to N8N Cloud. Your workflows can connect to any API, database, or service. Common starting points for SMBs:
- Connect to Google Sheets for data logging (see our N8N + Google Sheets guide)
- Pull data via HTTP requests to connect any API without a dedicated node
- Trigger workflows from webhooks when form submissions, payments, or CRM events fire
One of our clients, a premium outdoor kitchen brand, runs their entire customer inquiry routing and follow-up system on a self-hosted N8N instance. The setup reduced their manual data entry overhead by 80% compared to their previous process. The full story is in our Le Marquier case study.
If you want to understand the financial case for N8N automation before investing more time in setup, our free ROI calculator gives you a concrete number in two minutes.
When to Use N8N Cloud Instead
Self-hosting is not always the right choice. Use N8N Cloud if:
- You are evaluating N8N for the first time and do not want infrastructure overhead
- Your team has no one comfortable managing a Linux server
- You run fewer than 2,500 executions per month (cloud pricing is competitive at this volume)
If you are not sure whether your business is ready to build out a full N8N automation stack, our AI readiness assessment helps you identify where automation will have the most immediate impact before committing engineering time.
For businesses that want the benefits of N8N without handling any of the infrastructure, our N8N automation service covers setup, workflow development, and ongoing support.
Frequently Asked Questions
How much does it cost to self-host N8N?
Self-hosting N8N on a VPS costs between $5 and $20 per month depending on the provider. A 2 vCPU, 4 GB RAM server from DigitalOcean, Hetzner, or Linode handles most small-business workloads. Compare that to N8N Cloud plans which start at $20/month with execution limits.
What is the minimum server spec for N8N?
N8N runs on 1 vCPU and 1 GB RAM for light workloads, but 2 vCPU and 2 GB RAM is the practical minimum for production. If you run more than 10 concurrent workflows or use AI nodes with large payloads, upgrade to 4 GB RAM. Storage depends on workflow execution history retention, but 20 GB SSD is a safe starting point.
Is self-hosted N8N secure?
Self-hosted N8N is secure when configured correctly. Use HTTPS with a valid SSL certificate, set strong authentication (basic auth or N8N's built-in user management), restrict the server firewall to ports 80, 443, and 22, and never expose the N8N port (default 5678) directly to the internet. Keep Docker images updated monthly.
Can I migrate from N8N Cloud to self-hosted?
Yes. Export your workflows from N8N Cloud using the menu in each workflow (Download as JSON) or the API. Import them into your self-hosted instance via Settings > Import Workflows. Credentials need to be re-entered manually since they are not exported for security reasons.
How do I update N8N when self-hosting with Docker?
Run: docker compose pull && docker compose up -d. This pulls the latest N8N image and restarts the container with zero downtime in most cases. Always back up your n8n_data volume before upgrading major versions.
Ready to Get Started?
Book a free 30-minute discovery call. We'll identify your biggest opportunities and show you exactly what AI automation can do for your business.