n8n Self-Hosted Setup Guide: From Zero to a Running Automation Server in One Afternoon
Self-hosting n8n gives you unlimited automation executions with no per-operation fees. This guide covers VPS setup, Docker, Nginx with SSL, and keeping n8n running reliably.


Self-hosting n8n gives you unlimited workflow executions, full data control, and no per-operation pricing ceiling. The trade-off is that you are responsible for the server. That sounds more intimidating than it is. A standard n8n self-hosted setup on a basic VPS takes two to three hours from start to a running production instance, and once it is up it requires almost no ongoing maintenance.
This guide covers the complete setup: choosing a server, installing n8n with Docker, setting up a reverse proxy with SSL, configuring basic security, and keeping n8n running reliably. If you're still deciding whether n8n is the right platform at all, n8n vs Make.com is worth reading first, and n8n's own comparison of the cloud and self-hosted editions covers what you give up by not paying for cloud.
What You Need Before You Start
A VPS. Any Linux VPS running Ubuntu 22.04 or 24.04 works. The minimum spec for a light n8n deployment is 1 CPU and 1GB RAM, but 2GB RAM is more comfortable if you are running multiple active workflows. Hetzner, DigitalOcean and Vultr are all reliable options, and a box of this size sits at the bottom of every provider's price list — low single figures per month at the time of writing, though check the current pricing page rather than trusting a number written in an article. Avoid the cheapest shared hosting — it will not run Docker.
A domain name. You need a domain or subdomain to set up SSL. Something like n8n.yourdomain.com works fine. You need to be able to add a DNS A record pointing to your server IP.
Basic command line comfort. You do not need to be a Linux administrator, but you need to be comfortable SSHing into a server and running commands. If you have never done this before, spend 30 minutes on a basic Linux command line tutorial first.
Step 1: Provision and Secure the Server
Spin up your VPS with Ubuntu 22.04. Most providers give you a root password or SSH key on creation. SSH in:
ssh root@YOUR_SERVER_IPUpdate the system packages first:
apt update && apt upgrade -yCreate a non-root user for day-to-day operations:
adduser n8nadmin
usermod -aG sudo n8nadminSet up a basic firewall. Allow SSH, HTTP, and HTTPS. Block everything else:
ufw allow OpenSSH
ufw allow 80
ufw allow 443
ufw enableIf your provider offers a firewall at the infrastructure level (Hetzner Firewall, DigitalOcean Firewall), configure that too. Defence in depth costs nothing extra.
Step 2: Install Docker and Docker Compose
N8n runs best in Docker. Install both:
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
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" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginVerify Docker is running:
docker run hello-worldAdd your user to the Docker group so you can run Docker commands without sudo:
usermod -aG docker n8nadminLog out and back in for the group change to take effect.
Step 3: Set Up n8n With Docker Compose
Create a directory for your n8n setup:
mkdir /opt/n8n && cd /opt/n8nCreate a docker-compose.yml file:
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
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/
- GENERIC_TIMEZONE=UTC
- N8N_ENCRYPTION_KEY=your_random_32_char_string_here
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:Replace n8n.yourdomain.com with your actual subdomain and generate a random string for N8N_ENCRYPTION_KEY (used to encrypt stored credentials). The n8n documentation is the reference for the rest of the environment variables.
Start n8n:
docker compose up -dN8n is now running on port 5678. Do not expose this port directly to the internet — put a reverse proxy in front of it with SSL.
Step 4: Set Up Nginx as a Reverse Proxy With SSL
Install Nginx and Certbot:
apt install -y nginx certbot python3-certbot-nginxCreate an Nginx server block for your subdomain:
nano /etc/nginx/sites-available/n8nPaste this configuration:
server {
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;
}
}Enable the site and test the Nginx config:
ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginxMake sure your DNS A record for n8n.yourdomain.com is pointing to your server IP before running Certbot. Then get a free SSL certificate:
certbot --nginx -d n8n.yourdomain.comCertbot automatically modifies your Nginx config to handle HTTPS and sets up auto-renewal. Your n8n instance is now accessible at https://n8n.yourdomain.com.
Step 5: Configure n8n and Create Your Owner Account
Open your browser and navigate to your n8n URL. You will be prompted to create an owner account with email and password. This is the admin account — store the credentials somewhere safe.
Once in, go through Settings to configure:
Community nodes. Enable community node installation if you want access to third-party n8n nodes beyond the built-in library.
User management. If multiple people will use this instance, set up user accounts with appropriate role assignments.
Timezone. Set your instance timezone to match your primary operating timezone.
Once the instance is live, How to Build an n8n Workflow covers building your first real automation on it.
Step 6: Keep n8n Running and Up to Date
Docker's restart: always setting in the compose file means n8n restarts automatically if it crashes or if the server reboots. But the server itself needs to be managed.
Enable automatic security updates to keep the OS patched without manual effort:
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgradesSet up a simple monitoring check. The free tier of UptimeRobot monitors your n8n URL every five minutes and sends an email alert if it goes down. It takes two minutes to configure and gives you visibility into any uptime issues.
To update n8n when a new version is released:
cd /opt/n8n
docker compose pull
docker compose up -dThat pulls the latest image and restarts the container. Your workflows, credentials, and data persist in the named volume and are not affected by the update.
Backing Up Your n8n Data
The n8n_data Docker volume contains your workflows, credentials, and execution history. Back it up regularly.
The simplest approach: export all workflows from the n8n UI (Settings > Import/Export) and store the JSON files in a separate location. Do this before every update and weekly in normal operation.
For a more automated approach, use a cron job to copy the volume data to a remote location or an object storage bucket like Backblaze B2 or Wasabi. For production instances handling business-critical automations, automated backups are not optional.
When planning scheduled backup jobs and other server-side cron tasks, the Cron Expression Generator produces correctly formatted cron strings without having to remember the syntax.
What to Build First
With n8n running, the most useful first workflows to build are ones that validate the setup is working end-to-end: a simple webhook test that receives a payload and posts a message to Slack, a scheduled workflow that checks a URL and alerts you if it is down, a basic HTTP request to an API you use regularly. n8n Webhook Tutorial covers the webhook side of that testing.
These are low stakes, fast to build, and confirm that webhooks, outgoing HTTP calls, and scheduled triggers are all working correctly on your instance before you depend on it for anything critical.
This exact self-hosted setup — VPS, Docker, Nginx, SSL — is what I put in place for clients with data sovereignty requirements or high execution volume where per-operation pricing stops making sense. If you want help designing your n8n workflow architecture or need a more complex deployment (multiple workers, queue mode, PostgreSQL backend), book a free 30-minute call. Bring your use case and expected workflow volume and we will design the right setup.
Frequently Asked Questions
Does exporting workflows actually back up everything?
No, and this is the assumption that costs people a weekend. Exporting workflows from the interface gives you the logic and nothing else: the credentials are not in those JSON files, and even if they were, they are encrypted with a key that lives in an environment variable rather than in the volume. A backup is only complete when it contains the workflow definitions, the n8n_data volume itself, and the encryption key stored somewhere separate from both. Restoring a volume without the matching key gives you an instance where every workflow is present and every connection fails to decrypt, which looks like a working restore right up until you try to run something.
Is self-hosting really cheaper than the cloud plan?
On the server bill, obviously. On the total, it depends entirely on what your time is worth and how much you run. A few pounds a month for a box that executes as much as you like beats per-execution pricing decisively at volume, and loses just as decisively if you run a handful of workflows and now own patching, backups, SSL renewal and the occasional two in the morning outage. The honest rule is that self-hosting pays when volume is high, when data cannot leave your infrastructure, or when you are technical enough that the maintenance is genuinely near zero for you. It rarely pays as a way to save a small subscription.
My webhook URL says localhost. Why?
Because n8n does not know what address the outside world reaches it on unless you tell it. The instance sits behind Nginx and only ever sees a request arriving at port 5678, so the URL it displays and hands to external services comes from WEBHOOK_URL and N8N_HOST. If either is missing, wrong, or still carries http while the site is on https, the copied production URL points somewhere unreachable and the sending system gets a connection error you will spend an hour blaming on the sender. Set both explicitly, then restart the container, because the values are read at start-up.
Do I need PostgreSQL rather than the default database?
Not at first. The default SQLite file is perfectly adequate for a single instance running a moderate number of workflows, and swapping it out on day one is optimisation ahead of a problem you may never have. The point to move is when execution history has grown large enough that the interface feels sluggish, when concurrent executions start contending for the database, or when you want queue mode with multiple workers, which needs a proper database anyway. Plan for the migration rather than fearing it, and take the decision on observed slowness rather than on principle.
How exposed is an instance sitting on the public internet?
More than the login screen suggests. Anything reachable at a public URL will be scanned within days, so the owner account password is the only thing between the internet and your credentials store, and the webhook endpoints are open by design because they have to be. Use a long unique password and enable two-factor authentication on every account, keep the container and the host patched, and restrict access to the editor by IP where the people who need it work from predictable addresses. Binding the container to localhost as in the compose file above matters too: without it, port 5678 answers directly and bypasses the proxy, SSL and everything else you configured.
If you would rather have this built than build it, I take on n8n deployment and workflow automation work through Fiverr.

Want this built against your real numbers?
A 30-minute call to scope the workflow, agent, or automation you actually need.
Have a workflow that's burning hours every week?
Bring me one real bottleneck. I'll tell you whether it's worth automating, and what it would take.