What a self-hosted n8n consists of
- n8n, the
n8nio/n8nimage, listening on port 5678. Its data directory,/home/node/.n8n, holds the SQLite database and the encryption key. - Traefik, in n8n's Compose guide, on ports 80 and 443. It gets certificates from Let's Encrypt through a TLS challenge and routes the subdomain to n8n. n8n's guide states the instance is only reachable over HTTPS.
- A DNS A record for the subdomain, pointing at the server's address, before the first start: the certificate request depends on it.
- Optionally, PostgreSQL and Redis. n8n uses SQLite out of the box. Postgres is configured with
DB_TYPE=postgresdb, and Redis enters with queue mode.
Webhooks are why this is a server and not a laptop. A trigger from Stripe, GitHub or a form posts to a public HTTPS URL that n8n learns from N8N_WEBHOOK_URL (WEBHOOK_URL before n8n 2.30.0), and it has to answer at any hour.
Setting it up with Docker Compose
- On a Linux server, install Docker Engine and the Compose plugin from Docker's instructions for your distribution, and check both answer.
- Create the A record for the subdomain, for example
n8n.example.com, pointing at the server. - Make a project directory with a
local-filesfolder, the folder n8n reads and writes at/files. - Write the
.envfile below with your domain, subdomain, time zone and certificate email. - Paste
compose.yamlfrom n8n's Docker Compose guide unchanged: Traefik on 80 and 443, n8n published on127.0.0.1:5678only, then8n_dataandtraefik_datavolumes. - Start it, then open the HTTPS address straight away.
docker --version
docker compose version
mkdir n8n-compose && cd n8n-compose
mkdir local-files
# .env
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Berlin
SSL_EMAIL=user@example.com
# compose.yaml: copy it from n8n's Docker Compose guide, then
sudo docker compose up -d
The first person to open the address gets n8n's owner sign-up screen, and there is no supported way to turn the login screen off. Create the owner account the moment the instance answers, with a password of at least eight characters, a number and a capital letter.
The encryption key and backups
On first launch n8n generates a random encryption key and saves it in ~/.n8n, inside the n8n_data volume, and uses it to encrypt every credential before it reaches the database. A database restored without that key holds credentials nothing can read. Back up the volume as a whole, or set N8N_ENCRYPTION_KEY yourself and keep that value somewhere outside the server.
With the containers stopped, Docker's own volume-backup pattern copies the data directory to a tarball you then move off the machine:
sudo docker compose stop
sudo docker run --rm --volumes-from n8n-compose-n8n-1 -v "$(pwd)":/backup ubuntu tar cvf /backup/n8n-data.tar /home/node/.n8n
sudo docker compose up -d
SQLite, Postgres and queue mode
SQLite is fine for one person's automations. Execution history is what grows: n8n prunes it by default at 14 days or 10,000 executions, and on SQLite the space pruning frees is reused, not returned to the disk, until a VACUUM runs (DB_SQLITE_VACUUM_ON_STARTUP does it at start).
Queue mode is the next step when one process cannot keep up: a main instance takes triggers and webhooks, Redis queues the executions, and worker instances run them. Set EXECUTIONS_MODE=queue on the main instance and every worker, and give every worker the same N8N_ENCRYPTION_KEY. n8n's docs say a distributed setup over SQLite is not supported, so queue mode means moving the database first.
Workers can be more processes on the same machine or more machines. In New York, managed Kubernetes runs the control plane for you and keeps your own dedicated servers as the workers.
Why a whole server for it
n8n holds the keys to every system it automates: API tokens, database passwords, OAuth grants. On a single-tenant machine those sit on hardware nobody else's workload shares, with root yours and no virtualization layer underneath. The container servers are delivered in about 30 minutes once payment is verified.
Workflows that move files and API payloads all day are traffic, and the port is unmetered: nothing counts the bytes in either direction. The machines and the network are ours, on our own autonomous system, AS19624, in New York, Miami, San Francisco, Amsterdam and Bucharest, so the instance can sit next to the systems it calls.
Firewall and updates
- Docker publishes around ufw. Docker's documentation says the two are incompatible: packets to a published port are routed before ufw's rules apply. That is why n8n's guide publishes 5678 on 127.0.0.1 only. Keep it that way, and expect 80 and 443 to be open whatever ufw says.
- Update deliberately. n8n ships a new minor version most weeks. The Compose update is
sudo docker compose pull, thendown, thenup -dfrom the project directory; to hold a version, replaceimage: n8nio/n8nincompose.yamlwith the exact version tag you tested. - Read access to files is fenced. The guide's
N8N_RESTRICT_FILE_ACCESS_TO=/fileslimits file nodes to thelocal-filesfolder.
When self-hosting is the wrong call
n8n's own guide recommends self-hosting for expert users and points everyone else to n8n Cloud: servers, containers, scaling and security become your job, and mistakes cost data and uptime. If nobody on the team wants to own updates and backups, a hosted plan is the honest answer.
Check the licence too. n8n's Sustainable Use License permits use for your own internal business purposes or for non-commercial or personal use; providing n8n to others is allowed only free of charge for non-commercial purposes, and files marked .ee. need an enterprise licence.
Questions
What does n8n need to be reachable for webhooks?
A public HTTPS address. n8n's Compose guide uses a subdomain with a DNS A record, Traefik with a Let's Encrypt certificate on ports 80 and 443, and N8N_WEBHOOK_URL set to that address so the URLs n8n hands out are correct.
Can I run n8n without the login screen?
No. n8n removed basic auth and the setting that disabled user management in version 1.0, and its docs say there is no supported way to disable the login. Create the owner account as soon as the instance starts, because the first visitor gets the sign-up screen.
Should I use SQLite or Postgres?
SQLite, the default, suits a single instance with modest history. Move to Postgres before queue mode, which n8n does not support over SQLite, or when execution data grows large; keep the n8n_data volume either way, since it still holds the encryption key.
What happens if I lose the encryption key?
Stored credentials become unreadable: n8n encrypts them with that key before saving them. Back up the n8n_data volume, or set N8N_ENCRYPTION_KEY yourself and store the value off the server; queue-mode workers need the same key.
Can I sell n8n workflows to clients from my server?
Building workflows for your own business is permitted; offering n8n itself to others is limited by the Sustainable Use License to free, non-commercial distribution. Read the licence, or ask n8n about a commercial agreement, before reselling access.
How soon is a server ready?
The container servers are delivered in about 30 minutes once payment is verified, with root access from the control panel. Installing Docker and starting n8n takes a few commands after that.