# How to Deploy n8n Securely on a VPS

- Link: https://offshorehosting.pk/how-to-deploy-n8n-securely-on-a-vps/
- Published: 2026-10-25T10:38:00+00:00
- Author: admin

# How to Deploy n8n Securely on a VPS

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](https://offshorehosting.pk/blog/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](https://offshorehosting.pk/blog/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.

    ```bash
    # 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:

    ```bash
    # 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:

 1. **The PostgreSQL database** (workflows, credentials in encrypted form, and execution
    data).
 2. **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).
 3. **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](https://offshorehosting.pk/blog/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](https://offshorehosting.pk/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/
 * SyncBricks — Install n8n on Ubuntu 24.04 VPS: Docker, Postgres, SSL 2026: https://
   syncbricks.com/self-hosting-n8n-on-ubuntu-24-04-a-step-by-step-guide/
 * MassiveGrid — How to Self-Host n8n on a High-Availability VPS (Complete Docker
   Guide): https://massivegrid.com/blog/self-host-n8n-docker-guide/
 * Cherry Servers — n8n Self-Hosting Requirements Guide (2026): https://www.cherryservers.
   com/blog/n8n-self-hosting-requirements

## Sources

 * https://stacksheriff.com/automation/install-n8n-docker-compose/
 * https://scriptxeno.github.io/posts/how-to-self-host-n8n-installation-guide/
 * https://syncbricks.com/self-hosting-n8n-on-ubuntu-24-04-a-step-by-step-guide/
 * https://massivegrid.com/blog/self-host-n8n-docker-guide/
 * https://www.cherryservers.com/blog/n8n-self-hosting-requirements
