Ernesto Ramírez

How to self host n8n with Dokku

Author

Ernesto Ramírez

Published date

n8n + dokku

Dokku is an open source PaaS (Platform as a Service) alternative to Heroku. It helps you build and manage the lifecycle of applications from building to scaling.

On the other hand, n8n is an "almost open-source", node-based workflow automation tool that helps users visually connect apps and services to automate repetitive tasks. Essentially, it is a software for low-code automations.

I've been using dokku the last two or three years and for me, it is just incredible. With a modest VPS you could host multiple applications and forget about expensive cloud providers like Render, Heroku or Vercel. You only need basic understanding on Linux, Networking & Docker.

In this post I'd like to show you how I self-hosted n8n inside a VPS running dokku.

Make sure before starting:

  1. VPS with SSH connection (preferably with a Debian based distribution)
  2. Dokku 0.30.0+
  3. Domain name pointing to the VPS host (for example, n8n.example.com)
  4. LetsEncrypt plugin for Dokku

TL;DR

1# 1. Application & Storage Initialization
2# Create the application in Dokku
3dokku apps:create n8n
4
5# Create the physical directory on the host for SQLite database and settings
6dokku storage:ensure-directory n8n --chown false
7
8# CRITICAL: n8n runs as the 'node' user (UID 1000).
9# We must adjust ownership so the container has write permissions on the host folder.
10sudo chown 1000:1000 /var/lib/dokku/data/storage/n8n
11
12# Mount the volume: maps the host directory to the node user's home in the container
13dokku storage:mount n8n /var/lib/dokku/data/storage/n8n:/home/node/.n8n
14
15# 2. Networking & Domain Identity
16# Set the domain where the instance will be reachable
17dokku domains:set n8n n8n.your-domain.com
18
19# Port mapping: n8n will listen internally on 443 (defined in config).
20# Dokku will expose 80 (HTTP) and 443 (HTTPS) to the outside world.
21dokku ports:set n8n http:80:443 https:443:443
22
23# 3. Environment Variables (Core Configuration)
24# Force internal port 443 and HTTPS protocol to ensure
25# correct callback URL generation for Webhooks and OAuth integrations.
26dokku config:set n8n \
27 N8N_HOST=n8n.your-domain.com \
28 N8N_PORT=443 \
29 N8N_PROTOCOL=https \
30 N8N_WEBHOOK_URL=https://n8n.your-domain.com \
31 TZ=America/Mexico_City \
32 GENERIC_TIMEZONE=America/Mexico_City \
33 N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
34 NODES_EXCLUDE="[]"
35
36# 4. Security (SSL Certificate)
37# Generate and enable an SSL certificate via Let's Encrypt plugin
38dokku letsencrypt:enable n8n
39
40# 5. Final Deployment
41# Pull the official image directly and trigger the Dokku build/deploy workflow
42dokku git:from-image n8n docker.n8n.io/n8nio/n8n:2.1.4
shell


Step by Step

1. Creation of the application & setup volumes

Ok, first things first. After entering our dokku host via SSH, we must create the dokku application and create the necessary volumes to run the application. We are going to use SQLite for this, but if you want to use Postgres, you need to create a Postgres instance and adapt configuration.

1# Create the main application
2dokku apps:create n8n
3
4# Create storage directories
5dokku storage:ensure-directory n8n --chown false
6
7# Adjust permissions to user 'node' (UID 1000) inside the container
8sudo chown 1000:1000 /var/lib/dokku/data/storage/n8n
9
10# Mount the volumes
11dokku storage:mount n8n /var/lib/dokku/data/storage/n8n:/home/node/.n8n
12
shell

2. Set up config variables

n8n is configured through environment variables, and for that, we are going to use dokku config. We must set in which port the app will be running and what protocol are we going to use.

Note: I know that you might think that the n8n container is not supposed to use port 443 because it is not responsible of SSL certificate, but if we don't do that, the callback URLS for OAUTH integrations will not work, since they will be pointing to another URL, like <host>:5678/callback

Another note: Here is where you should put your Postgres instance connection string. If using the postgres plugin, you should first link and then copy the connection string in the proper environment variables used by n8n.

1dokku config:set n8n \
2 N8N_HOST=<your_domain_name> \
3 N8N_PORT=443 \
4 N8N_PROTOCOL=https \
5 N8N_WEBHOOK_URL=https://<your_domain_name> \
6 TZ=America/Mexico_City \
7 GENERIC_TIMEZONE=America/Mexico_City \
8 N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
9 NODES_EXCLUDE="[]"
shell

3. Configure network

We are planning to expose our n8n instance to internet and use HTTPS for it. So we should have the right mapping to it.

1dokku domains:set n8n <your_configured_domain>
2# Map the 443 port configured before to HTTP and HTTPS exposed endpoints
3dokku ports:set n8n http:80:443 https:443:443
shell

4. Issue SSL certificate

Using the dokku letsencrypt plugin, we must enable a SSL certificate for our app

1dokku letsencrypt:enable n8n
shell

5. Deploy image

The final step to finish our installation is to actually deploying the docker image.

1dokku git:from-image n8n docker.n8n.io/n8nio/n8n:2.1.4
shell

After deploying the image we could see the URL for our n8n installation and start using it with no issues. Cheers!

Conclusion

Hosting software shouldn't be painful, and dokku get us covered. It leverages Docker for hosting different applications on the same host, and n8n is not the exception. With this simple configuration, you could host your personal nonsense automations :)