Author: [TO BE CONFIRMED] · Published: October 25, 2026
An n8n instance holds credentials for your email, CRM, spreadsheets and payment tools, and can execute code and call APIs on your behalf. Deployed carelessly — no HTTPS, the port open, no backup — it is a credential store waiting to be found. Deployed carefully, it is reliable infrastructure.
This guide walks through a secure deployment on a VPS, using Docker Compose with PostgreSQL, behind a reverse proxy with HTTPS. It assumes a current Ubuntu LTS server and a domain you control. Commands are given with prerequisites and warnings; do not run them on a production server without understanding them, and test on a staging server first if you are unsure.
Warning: the steps below involve server administration, firewall changes, and credentials. A mistake can lock you out of the server or expose the instance. If you do not have Linux server experience, use a managed option or hire someone who does — see Dedicated Server Management Responsibilities for what “running it yourself” entails.
Before you start
A VPS with at least 2 vCPU and 4 GB of RAM for a small production instance, and 40–80 GB of NVMe SSD storage. n8n itself starts comfortably on less, but PostgreSQL and a few active workflows need the headroom. See How to Choose n8n Hosting in 2026 for sizing.
A domain or subdomain for n8n (for example n8n.example.com), with a DNS A record pointing at the server. Webhook and OAuth callback URLs are built from this address, so set it before the first boot.
A current n8n version. As of late 2026, n8n is on the 2.x line (version 2.0 was released in December 2025 as a hardening release). Pin the Docker image to a specific version tag rather than latest in production, so updates happen only when you decide. Check n8n’s official release notes for the current version at deploy time.
The licence position. Confirm that your use is allowed under the Sustainable Use License — internal business use is allowed; hosting n8n for your customers is not. See the licensing section of our companion guide.
Step 1: prepare the server
Update the server and install Docker, then create a non-root user for the deployment and a directory for the stack. Do this over SSH with key authentication — disable password-only root SSH login before the server carries real credentials.
# Update the system first — never deploy on an unpatched server
sudo apt update && sudo apt upgrade -y
# Install Docker using the official script, then verify it
curl -fsSL https://get.docker.com | sh
docker compose version
Create a dedicated directory (for example /opt/n8n) and restrict its permissions, because it will hold secrets. Do not store secrets in a world-readable file, and never commit the environment file to version control.
Step 2: set the encryption key first — this is the step people lose
n8n encrypts stored credentials with N8N_ENCRYPTION_KEY. Set your own key before the first boot and keep a copy outside the server, in a password manager or a secrets store.
Warning: if you do not set this key, n8n generates a random one on first start and saves it inside the n8n data folder. If that folder is later discarded, or you restore a database backup with a different key, every saved credential becomes undecryptable. There is no recovery from that — you must re-enter every credential by hand. This is the single most common cause of a painful n8n rebuild.
Generate a strong random key (32 characters or more) and store it in a .env file alongside the Compose file:
# Generate a key — keep the output in your password manager, not just on the server
openssl rand -hex 32
Also generate strong, unique passwords for the PostgreSQL user and for the n8n owner account, and store them the same way. Never reuse a password from another service.
Step 3: write the Docker Compose file
n8n’s own documentation recommends Docker Compose for self-hosting, and the current recommended layout is three services — postgres, n8n, and a separate n8n-runner container that isolates code execution from the n8n core process. Older tutorials show two services; follow the current official layout in n8n’s deployment documentation (under docs.n8n.io/deploy/host-n8n/) and in the official n8n-io/n8n-hosting repository at deploy time, because the recommended setup has changed before.
The essential points, whichever exact file you use from the official source, are:
PostgreSQL, not SQLite, for production. SQLite is fine for testing; production needs PostgreSQL for reliability and concurrency.
A healthcheck on PostgreSQL, so n8n only starts after the database is ready.
Named volumes for the database and for n8n data, so data survives container recreation.
The n8n port bound to localhost only (for example 127.0.0.1:5678:5678), never directly to the internet. A reverse proxy in front handles public traffic and HTTPS.
The webhook URL set to your public HTTPS address with a trailing slash, for example https://n8n.example.com/. On current n8n 2.x, use N8N_WEBHOOK_URL; the older WEBHOOK_URL variable is deprecated from n8n 2.35.0 and logs a warning.
A pinned image tag (for example n8nio/n8n:2.x.y), not latest.
The timezone set explicitly (GENERIC_TIMEZONE and TZ), so scheduled workflows run when you expect.
Step 4: put a reverse proxy with HTTPS in front
Never expose n8n’s port directly. Use a reverse proxy — Caddy (which obtains and renews certificates automatically), Traefik, or Nginx with a Let’s Encrypt certificate — that listens on ports 80 and 443 and forwards to n8n on localhost. Only ports 22 (SSH, restricted), 80 and 443 should be open in the firewall.
Verify after setup: visit https://n8n.example.com and confirm the certificate is valid, that plain HTTP redirects to HTTPS, and that http://server-ip:5678 from the internet does not reach n8n. If it does, the port binding is wrong and the instance is exposed.
Step 5: lock down access
Create the owner account immediately on first login, with a strong, unique password and, where available, multi-factor authentication. Do not leave the instance in its unregistered state.
Restrict who can reach the editor. If only your team uses n8n, consider restricting access by IP allow-list, VPN, or a reverse-proxy authentication layer in front of the editor, while leaving webhook endpoints reachable as needed.
Use separate credentials per integration, with the least privilege each integration needs. A credential that can read your whole mailbox should not be used by a workflow that only needs to send one notification.
Block environment-variable access from Code nodes where your setup supports it (N8N_BLOCK_ENV_ACCESS_IN_NODE). n8n 2.0 made task runners the default and tightened Code-node access for exactly this reason — a workflow that can read environment variables can read secrets.
Keep the server patched and Docker updated, and review who has SSH access regularly.
Step 6: backups — database, data, and key
Back up three things, together, on a schedule:
The PostgreSQL database (workflows, credentials in encrypted form, and execution data).
The n8n data volume (configuration and the encryption key if it was auto-generated — but you set your own key in Step 2, so the key lives in your password manager, not only on the server).
The Compose file and .env (without committing them to a public repository).
Store the backups off the server, in a different failure domain, and test the restore on a staging server at least quarterly. A restore test that uses the backed-up database with the backed-up encryption key is the only proof that your credentials will survive a rebuild. See Server Snapshots vs Backups for why a snapshot alone is not a backup.
Step 7: updates and monitoring
Update deliberately, not automatically. Pull a pinned new version, back up first, update on staging if you can, and check the release notes for breaking changes — especially around Code nodes, webhooks, and environment variables in the 2.x line.
Queue mode and workers — a note, not a starting point
n8n supports a queue execution mode with worker processes and Redis for higher throughput. [TO BE CONFIRMED: whether Offshore Hosting offers queue/worker configurations for n8n, and on which plans.] Do not enable queue mode on a first deployment unless you genuinely need it. Start with the single-instance mode in this guide, measure your execution volume, and scale when the numbers say so.
The bottom line
A secure n8n deployment is a short list done properly: a patched server, Docker Compose from the official source with PostgreSQL, a reverse proxy with HTTPS and no directly exposed port, an encryption key set before the first boot and stored outside the server, least-privilege credentials, off-server backups, and a tested restore. Do those things and n8n becomes dependable infrastructure. Skip them, and the first incident — a lost key, an exposed instance, or a failed restore — will cost far more than the hour it took to do it right.
For a VPS to deploy n8n on, see our VPS hosting plans. [TO BE CONFIRMED: Offshore Hosting VPS specifications for n8n, and whether any managed n8n or queue/worker offering exists.]
Sources
StackSheriff — n8n Docker Compose: Production Setup Guide (2026): https://stacksheriff.com/automation/install-n8n-docker-compose/
ScriptXeno — How to Self-Host n8n: A Real Installation Guide (Docker, 2026): https://scriptxeno.github.io/posts/how-to-self-host-n8n-installation-guide/
Email on your own domain looks professional and stays yours when you change providers. This guide explains what business email hosting involves, how it differs from free webmail, and the DNS and deliverability pieces that make it work.
Latency figures are widely quoted and widely misunderstood. This guide explains what ping measures, which hop actually matters, and the limits of what a VPS can do.
Webhooks, queue mode, and execution retention decide whether n8n stays fast or slowly fills its database. This guide explains each one and the settings that matter.