GHOSTVPS / Automation

Start n8n privately with Docker and an SSH tunnel

Run a small private n8n editor without publishing port 5678 to the internet.

Updated · GhostVPS

Before you start

A fresh Linux VPS with sudo, Docker Engine 28 or newer, Compose v2 and working SSH. Follow Docker’s official installation instructions first. This guide uses SQLite and one container for evaluation/manual workflows, not a production cluster or public webhook service. Do not run it over an existing preinstalled n8n service.

Check the prerequisites

Run the two checks below on your VPS. Both must succeed. Use the official Docker installation reference if either component is missing; do not pipe an unknown installation script into a root shell. Plan resources for your actual workflows rather than treating a sample RAM figure as a guaranteed minimum.

Your VPS · Linux terminal

sudo docker version
sudo docker compose version
Check the prerequisites. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.
Check the prerequisites. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.

Create an isolated project and select a version

Create a new project directory and .env file. Replace REPLACE_WITH_REVIEWED_STABLE_VERSION with an exact supported stable version from the official n8n release list before proceeding. Review its security and upgrade notes. Do not leave the placeholder or use an unreviewed moving tag.

Your VPS · Linux terminal

mkdir -m 700 ~/n8n-private
cd ~/n8n-private
nano .env

File contents

N8N_VERSION=REPLACE_WITH_REVIEWED_STABLE_VERSION
Create an isolated project and select a version. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.
Create an isolated project and select a version. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.

Save a loopback-only Compose file

Save the following as compose.yaml in the project directory. The only published address is 127.0.0.1. The named volume retains n8n’s database and generated encryption key across container recreation. Do not change the mapping to 0.0.0.0 or mount the Docker socket into this container.

File contents

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION:?Set N8N_VERSION in .env}
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      TZ: Etc/UTC
      GENERIC_TIMEZONE: Etc/UTC
      N8N_HOST: localhost
      N8N_PORT: "5678"
      N8N_PROTOCOL: http
      N8N_EDITOR_BASE_URL: http://localhost:5678
      N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
    volumes:
      - n8n_data:/home/node/.n8n
volumes:
  n8n_data:
Save a loopback-only Compose file. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.
Save a loopback-only Compose file. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.

Validate the configuration and start

First run only the permission and config checks. If validation reports an error, fix the file before running pull or up. After start, compose ps should show n8n running. On failure inspect the logs in the final step. Do not expose the editor publicly to work around a tunnel problem.

Your VPS · Linux terminal

chmod 600 .env &&
grep -Eq '^N8N_VERSION=[0-9]+[.][0-9]+[.][0-9]+$' .env &&
sudo docker compose config --quiet &&
sudo docker compose pull &&
sudo docker compose up -d &&
sudo docker compose ps
Validate the configuration and start. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.
Validate the configuration and start. Actual rootless Docker lab: sudo is not needed in this setup. n8n 2.45.5 is the recorded demo version, not a recommendation for the latest production release.

Connect through your own SSH tunnel

On your own computer, replace the example account/address and run the SSH command below. Verify the host fingerprint through a trusted channel. Keep this terminal open and visit http://localhost:5678 in a browser on that same computer. Create your owner account there. If local port 5678 is busy, use 15678 on the left side and browse localhost:15678.

Your computer · terminal

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:5678:127.0.0.1:5678 deploy@203.0.113.10

Real screenshots from an isolated n8n 2.45.5 demo. Interface details can vary by version. Open an image to view it at full size.

Empty n8n owner-account setup form
Create the owner account after opening n8n through the private SSH tunnel. This form is shown before any credentials are entered.

Verify, back up and plan public access separately

Create a manual-trigger workflow with a simple non-secret test value, run it and confirm execution succeeds. Logs may contain sensitive data; redact before sharing. Make a consistent backup of the named volume, encryption key and configuration before upgrades; do not use down -v. Public webhooks need a separate domain/TLS/reverse-proxy setup using current n8n documentation. Never disable secure cookies to bypass an access error.

Your VPS · Linux terminal

sudo docker compose logs --tail=50 n8n

For this check, connect Manual Trigger to Edit Fields (Set). Add message (String) = GhostVPS tutorial check and verified (Boolean) = true. Save, choose Execute, then open the Edit Fields output and verify both values.

Edit Fields parameters for message and verified
In Edit Fields, add the non-secret sample message and the verified Boolean value.
Successful n8n workflow with Manual Trigger and Edit Fields
The two-node demonstration after a real successful manual execution.
n8n output with the sample message and verified set to true
Actual output from Edit Fields: the sample message and verified = true.

Official references