Skip to content
Automation
Skill

/n8n-self-hosting

Deploy a production self-hosted n8n end-to-end to a fresh Linux VM over SSH, using Docker Compose behind a Caddy reverse proxy with automatic HTTPS. Use whenever the user wants to self-host, install, set up, provision, or deploy n8n on their own server/VPS/box (Hetzner,

From plugin
n8n-mcp-skills
6k15 skills3 hooks
Install
$ npx -y skills add czlonkowski/n8n-skills --skill n8n-self-hosting --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/n8n-self-hosting

Context preview

The summary Claude sees to decide when to auto-load this skill.

Deploy a production self-hosted n8n end-to-end to a fresh Linux VM over SSH, using Docker Compose behind a Caddy reverse proxy with automatic HTTPS. Use whenever the user wants to self-host, install, set up, provision, or deploy n8n on their own server/VPS/box (Hetzner,

SKILL.md

n8n-self-hosting.SKILL.md
name: n8n-self-hosting
description: Deploy a production self-hosted n8n end-to-end to a fresh Linux VM over SSH, using Docker Compose behind a Caddy reverse proxy with automatic HTTPS. Use whenever the user wants to self-host, install, set up, provision, or deploy n8n on their own server/VPS/box (Hetzner, DigitalOcean, AWS EC2, bare metal, etc.) — in either single/regular mode or queue mode with workers — or to update, back up, restore, or harden such an instance. This is for SELF-HOSTED n8n (Docker), not n8n Cloud and not building workflows. The skill makes the agent ask single-vs-queue first, collect the domain/SSH/timezone inputs, generate fresh secrets on the box, and bring the stack up with TLS. Trigger on "deploy n8n", "self-host n8n", "install n8n on my server", "n8n docker compose", "n8n queue mode / workers / scaling", "n8n reverse proxy / SSL", or "back up / update my n8n".

Deploying self-hosted n8n

This skill takes a **fresh Linux VM** (Ubuntu/Debian, root or sudo SSH) to a **running, HTTPS, production n8n** via Docker Compose behind **Caddy** (automatic Let's Encrypt TLS). It is for **self-hosted n8n on Docker** — not n8n Cloud, and not for building workflows (that's the rest of this pack).

Two deployment modes. The architectures differ, so **pick the mode before doing anything**.

You drive this end-to-end over SSH: preflight → install Docker → lay down the project → generate secrets → launch → verify TLS → hand off. The template files live in `assets/`; the per-mode and security depth live in the reference files named below.

Rule 0 — choose the mode (ask the user)

Do not guess. Ask, then commit to one:

| | **Single / regular** | **Queue** | |---|---|---| | Processes | one n8n | main + N workers | | Extra services | none (SQLite) | Redis (queue) + Postgres (DB) | | Executes workflows | in the main process | on workers, in parallel | | Good for | 1 user, light/moderate load, simplest ops | high volume, heavy/long executions, horizontal scale | | Compose | `assets/docker-compose.single.yml` | `assets/docker-compose.queue.yml` | | Deep dive | **`SINGLE_MODE.md`** | **`QUEUE_MODE.md`** |

If unsure, start **single** — it's the simplest correct thing and covers most needs. Moving to queue later means swapping the compose file and migrating SQLite→Postgres, so if the user already expects real volume, start **queue**.

Rule 1 — secret hygiene (non-negotiable)

A misstep here leaks client credentials. Be diligent:

1. **Generate every secret fresh, on the target box.** Never copy an encryption key, DB password, or `.env` from another n8n instance into this one. See `SECURITY.md` for the `openssl` commands. 2. **Secrets live only in `.env`** (mode 600), referenced by the compose as `${VAR}`. Never inline a secret into `docker-compose.yml`, the Caddyfile, or anything you commit. 3. **The `N8N_ENCRYPTION_KEY` is sacred.** It encrypts every stored credential. If it's lost or changes, all saved credentials become undecryptable. Set it explicitly, and tell the user to back it up **off the box**. Don't echo it into long-lived logs or chat history beyond what's needed to hand it over. 4. **Never expose internal services.** Only Caddy (80/443) is public. n8n (5678), Postgres (5432), Redis (6379) stay on the private Docker network — the templates already omit their host port mappings. Don't add them. 5. **`.env` and Caddy's `caddy_data` volume (the issued certs + ACME account key) are not artifacts to share.** If you're working inside a git repo, confirm `.env` is git-ignored before any commit.

Inputs to collect up front

  • **SSH target** — `user@host` and how you authenticate (key path or the user confirms the agent already has access). Root or a sudo user.
  • **Domain** — the full hostname n8n will live at, e.g. `n8n.example.com` (→ `SUBDOMAIN=n8n`, `DOMAIN_NAME=example.com`). The user must control its DNS.
  • **TLS email** — for Let's Encrypt (`SSL_EMAIL`).
  • **Timezone** — IANA name for Schedule/Cron nodes (e.g. `Europe/Warsaw`), else `Etc/UTC`.
  • **Mode** — single or queue (Rule 0). Queue → confirm the box has enough RAM (rough floor ~4 GB; each worker wants ~1–2 GB).

The deploy flow

Work through these in order. `SINGLE_MODE.md` / `QUEUE_MODE.md` give the mode-specific command detail; `SECURITY.md` covers secret generation and hardening; `DAY2.md` covers update/backup/restore.

1. Preflight (the cheapest failure is the one you catch here)

  • SSH in; confirm the OS is Debian/Ubuntu-like (`. /etc/os-release`).
  • **DNS must already point at the box.** Compare the box's public IP (`curl -s ifconfig.me`)

with `dig +short <fqdn>` (run it from the box AND ideally your laptop). If they don't match, **stop** — Caddy's ACME challenge will fail. Have the user create the A record, wait for it to propagate, then continue.

  • Ports **80 and 443** must be reachable from the internet. Check the host firewall AND any

cloud security group / network firewall (Hetzner Cloud, AWS SG, etc.) — these are outside the box and a common silent blocker.

2. Install Docker (if absent)

  • Check `docker --version` and `docker compose version`. If missing, install Docker Engine +

the Compose plugin (Docker's official `get.docker.com` script on Ubuntu/Debian is fine). Re-check `docker compose version` before proceeding.

3. Lay down the project

  • Pick `DATA_FOLDER` — an **absolute path**, e.g. `/opt/n8n`. The `DATA_FOLDER` value in `.env`

**must equal this exact directory** (the compose mounts `${DATA_FOLDER}/caddy_config/Caddyfile`, and `init-data.sh` is mounted via a relative `./` path), so always run `docker compose` from here. Create it, plus `caddy_config/` and `local_files/` inside.

  • **Get the template files onto the box.** They live in this skill's `assets/` on *your* machine,

not on the server — transfer each one. Either `scp` them up, or (no local copy needed) write each file's contents over SSH, e.g. `ssh <target> 'ca

Read more
Ships withn8n-mcp-skills

Expert Claude Code skills for building flawless n8n workflows using the n8n-mcp MCP server

Get the whole plugin

Other skills on n8n-mcp-skills.