How to Self-Host n8n: Complete Docker + VPS Guide

How to Self-Host n8n: The Complete Docker Setup Guide

Self-hosting n8n gives you full control over your automation platform — no execution limits, no monthly fees, and complete data privacy. But setting it up properly requires getting several pieces right: the server, Docker, the database, a reverse proxy, SSL, backups, and monitoring.

I am Javier, a startup consultant in Chile, and I have been self-hosting n8n for over two years. My instance runs 24/7 on a dedicated machine, handling hundreds of workflows for content pipelines, CRM syncs, email automation, and API integrations. I have gone through the setup process multiple times, made plenty of mistakes, and learned what actually works in production.

This guide walks you through the entire process, from choosing a server to having a production-ready n8n instance with SSL, automated backups, and basic monitoring. No shortcuts, no missing steps.

Why Self-Host n8n?

Before we get into the setup, let me explain why self-hosting is worth the effort.

Cost savings: n8n Cloud starts at around 20 euros per month and charges based on executions. Self-hosting on a small VPS costs 5 to 10 dollars per month with unlimited executions. If you run a lot of workflows, the savings add up fast.

No execution limits: Cloud plans cap your monthly executions. Self-hosted n8n has no limits. Process as many items as your server can handle.

Data privacy: Your data stays on your server. No third party sees your API keys, customer data, or workflow logic. For businesses handling sensitive information, this is non-negotiable.

Full control: You can install community nodes, use npm packages in Code nodes, configure environment variables, and customize n8n however you need. No restrictions.

Performance: Dedicated server resources mean your workflows run faster and more reliably than shared cloud infrastructure.

If you want to test n8n before committing to self-hosting, start with n8n cloud to learn the platform. You can migrate to self-hosting later without losing your workflows.

Step 1: Choose Your Server

You need a VPS (Virtual Private Server) to host n8n. Here are my two recommended providers, both proven and affordable.

Option A: DigitalOcean

DigitalOcean is beginner-friendly with excellent documentation.

Recommended droplet: 2 vCPU, 4 GB RAM, 80 GB SSD ($24/month)
Minimum viable: 1 vCPU, 2 GB RAM, 50 GB SSD ($12/month)
Region: Choose the closest to your users
OS: Ubuntu 22.04 LTS or 24.04 LTS

To create a droplet:

1. Sign up at digitalocean.com
2. Click Create > Droplets
3. Select Ubuntu 22.04 LTS
4. Choose the Regular plan with 2 vCPU / 4 GB RAM
5. Select your preferred region
6. Add your SSH key (highly recommended over password auth)
7. Click Create Droplet

Option B: Hetzner

Hetzner offers significantly better pricing for equivalent specs, especially for European users.

Recommended server: CPX21 — 3 vCPU, 4 GB RAM, 80 GB SSD (around 7 euros/month)
Minimum viable: CX22 — 2 vCPU, 4 GB RAM, 40 GB SSD (around 4 euros/month)
Region: Nuremberg, Falkenstein, or Helsinki
OS: Ubuntu 22.04 LTS or 24.04 LTS

Hetzner’s setup process is similar to DigitalOcean. Create an account, add an SSH key, and provision a server.

My Recommendation

For most users, Hetzner’s CPX21 gives you the best value. I use Hetzner for my own instance and it has been reliable. If you prefer a more polished UI and more data center locations, DigitalOcean is a great choice too.

Step 2: Initial Server Setup

Once your server is running, SSH into it:

[Code block – see full guide at n8n.io/docs]

Update the system

[Code block – see full guide at n8n.io/docs]

Create a non-root user

Running everything as root is a security risk. Create a dedicated user:

[Code block – see full guide at n8n.io/docs]

Copy your SSH key to the new user:

[Code block – see full guide at n8n.io/docs]

Now log out and reconnect as the new user:

[Code block – see full guide at n8n.io/docs]

Configure the firewall

[Code block – see full guide at n8n.io/docs]

This allows SSH access and web traffic while blocking everything else.

Set up fail2ban (optional but recommended)

Fail2ban protects against brute-force SSH attacks:

[Code block – see full guide at n8n.io/docs]

Step 3: Install Docker and Docker Compose

Docker is the easiest way to run n8n. Here is how to install it on Ubuntu.

Install Docker

[Code block – see full guide at n8n.io/docs]

Log out and back in for the group change to take effect:

[Code block – see full guide at n8n.io/docs]

Verify Docker installation

[Code block – see full guide at n8n.io/docs]

Both commands should return version numbers. Docker Compose is included with modern Docker installations.

Step 4: Set Up n8n with Docker Compose

Now for the main event. Create a directory structure for n8n:

[Code block – see full guide at n8n.io/docs]

Create the Docker Compose file

Create `docker-compose.yml`:

[Code block – see full guide at n8n.io/docs]

Important: Replace these values before starting:

– `n8n.yourdomain.com` — your actual domain
– `your_secure_password_here` — a strong password for PostgreSQL (use the same in both places)
– `your_admin_password_here` — a strong password for the n8n admin interface
– `America/Santiago` — your timezone (find yours at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)

Why PostgreSQL instead of SQLite?

n8n defaults to SQLite, which is fine for testing. But for production, PostgreSQL is strongly recommended because:

– Better performance under concurrent load
– Proper data integrity and crash recovery
– Easier backups and replication
– Required for queue mode if you ever need to scale

Start n8n

[Code block – see full guide at n8n.io/docs]

Check that both containers are running:

[Code block – see full guide at n8n.io/docs]

You should see both `n8n` and `n8n-postgres` with status “Up”. Check the logs to make sure there are no errors:

[Code block – see full guide at n8n.io/docs]

You should see n8n starting up and eventually a message like “n8n ready on 0.0.0.0, port 5678”. Press Ctrl+C to exit the log view.

At this point, n8n is running on port 5678. You could access it at `http://your-server-ip:5678`, but we want proper SSL and a domain name. That comes next.

Step 5: Set Up Nginx Reverse Proxy

Nginx sits in front of n8n, handles SSL termination, and routes traffic to the Docker container.

Install Nginx

[Code block – see full guide at n8n.io/docs]

Create the Nginx configuration

Create a new site configuration:

[Code block – see full guide at n8n.io/docs]

Add the following configuration:

[Code block – see full guide at n8n.io/docs]

Replace `n8n.yourdomain.com` with your actual domain.

Enable the site

[Code block – see full guide at n8n.io/docs]

The `nginx -t` command tests the configuration. Only proceed if it says “test is successful.”

Point your domain

Before setting up SSL, point your domain to your server:

1. Go to your domain registrar (Namecheap, Cloudflare, etc.)
2. Create an A record: `n8n.yourdomain.com` pointing to your server IP
3. Wait for DNS propagation (usually 5 to 30 minutes)

Verify that the domain resolves:

[Code block – see full guide at n8n.io/docs]

This should return your server IP address.

Step 6: Set Up SSL with Let’s Encrypt

SSL is not optional. It encrypts traffic between your browser and n8n, protecting your credentials and data.

Install Certbot

[Code block – see full guide at n8n.io/docs]

Obtain and install the certificate

[Code block – see full guide at n8n.io/docs]

Certbot will:

1. Ask for your email address (for renewal notices)
2. Ask you to agree to the terms of service
3. Ask about the EFF newsletter (optional)
4. Automatically configure Nginx with SSL
5. Set up automatic renewal

Verify auto-renewal

[Code block – see full guide at n8n.io/docs]

If this succeeds, your certificate will renew automatically every 90 days. Certbot adds a systemd timer that handles this.

Test your setup

Open your browser and go to `https://n8n.yourdomain.com`. You should see the n8n login page with a valid SSL certificate (the padlock icon in your browser’s address bar).

Log in with the credentials you set in the Docker Compose file.

Step 7: Set Up Automated Backups

Backups are essential. Losing your workflows and credentials would be painful. Here is a backup strategy that covers both the database and n8n data.

Create a backup script

[Code block – see full guide at n8n.io/docs]

Add the following script:

[Code block – see full guide at n8n.io/docs]

Make it executable:

[Code block – see full guide at n8n.io/docs]

Test the backup

[Code block – see full guide at n8n.io/docs]

Check that backup files were created:

[Code block – see full guide at n8n.io/docs]

Schedule automatic backups with cron

[Code block – see full guide at n8n.io/docs]

Add this line to run backups daily at 3 AM:

[Code block – see full guide at n8n.io/docs]

Off-site backup (recommended)

Local backups protect against data corruption but not server failure. For off-site backups, consider syncing to an object storage service:

[Code block – see full guide at n8n.io/docs]

Popular options include Backblaze B2 (very cheap), DigitalOcean Spaces, or AWS S3.

Restoring from backup

If you ever need to restore:

[Code block – see full guide at n8n.io/docs]

Step 8: Set Up Monitoring

You want to know if n8n goes down before your workflows start failing.

Basic health check with a cron job

Create a simple monitoring script:

[Code block – see full guide at n8n.io/docs]

[Code block – see full guide at n8n.io/docs]

[Code block – see full guide at n8n.io/docs]

Add to cron to run every 5 minutes:

[Code block – see full guide at n8n.io/docs]

Docker resource monitoring

Keep an eye on resource usage:

[Code block – see full guide at n8n.io/docs]

Log monitoring

Check n8n logs for errors:

[Code block – see full guide at n8n.io/docs]

Step 9: Updating n8n

Keeping n8n updated ensures you get new features, bug fixes, and security patches.

Update process

[Code block – see full guide at n8n.io/docs]

Important: Always back up before updating:

[Code block – see full guide at n8n.io/docs]

Pin to a specific version (optional)

If you want more control over updates, pin to a specific version in your docker-compose.yml:

[Code block – see full guide at n8n.io/docs]

Instead of:

[Code block – see full guide at n8n.io/docs]

This way, you update only when you explicitly change the version number.

Step 10: Production Hardening

A few additional steps to make your setup more robust.

Increase system limits

Add to `/etc/sysctl.conf`:

[Code block – see full guide at n8n.io/docs]

Apply:

[Code block – see full guide at n8n.io/docs]

Docker restart policy

The `restart: always` in our Docker Compose file ensures containers restart after a crash or server reboot. Verify this works:

[Code block – see full guide at n8n.io/docs]

Both containers should be running.

Enable unattended security updates

[Code block – see full guide at n8n.io/docs]

This automatically installs security patches for Ubuntu.

Limit n8n resource usage (optional)

Add resource limits to the n8n service in docker-compose.yml:

[Code block – see full guide at n8n.io/docs]

This prevent