Skip to content

/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, provision, or deploy n8n on their own server/VPS (Hetzner, DigitalOcean, AWS

From plugin
n8n-mcp-skills
6.6k15 skills3 hooks

Claude Code

$ npx -y skills add czlonkowski/n8n-skills --skill n8n-self-hosting --agent claude-code

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, provision, or deploy n8n on their own server/VPS (Hetzner, DigitalOcean, AWS EC2, bare metal) — single/regular mode or queue mode with workers — or to update, back up, restore, or harden such an instance, or make Python Code nodes run on it (task runners). For SELF-HOSTED n8n (Docker), not n8n Cloud and not building workflows. The skill makes the agent ask single-vs-queue first, collect domain/SSH/timezone inputs, generate fresh secrets on the box, and bring the stack up with TLS. Trigger on "deploy n8n", "self-host n8n", "n8n docker compose", "n8n queue mode / workers", "n8n reverse proxy / SSL", "back up / update my n8n", "Python runner unavailable" / "n8nio/runners sidecar", or "we don't want to give every user the OAuth client secret" / "enable Sign in with Google" (credential overwrites).

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).
  • **Optional modules** — some features (currently **Agents**) are backend modules that stay off

unless listed in `N8N_ENABLED_MODULES`. Ask only if the user brings one up; if they do, read the modules section of `QUEUE_MODE.md` before enabling it, because in queue mode it has to reach the workers as well.

  • **Python Code nodes / who edits workflows** — ask *"Will workflows use Python Code nodes, or

will anyone besides you edit workflows?"* A yes to either means task runners in **external mode**: a `n8nio/runners` sidecar (one per worker in queue mode). The stock `n8nio/n8n` image has no Python 3, so in the default internal mode every Python Code node fails with `Python runner unavailable: Python 3 is missing from this system`. Read `TASK_RUNNERS.md` before step 3.

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

Read more
@czlonkowski
Ships withn8n-mcp-skills

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

Stars on GitHub

Momentum

stars in total
6.6k
Star history of czlonkowski/n8n-skills on GitHub, a chart by star-history.com

Other skills on n8n-mcp-skills.

n8n-agents
Auto-invoked

n8n-agents

Design n8n AI agents the right way. Use when building or editing any @n8n/n8n-nodes-langchain.* AI node — an AI Agent, LLM chain,…

n8n-code-python
Auto-invoked

n8n-code-python

Write Python in n8n Code nodes (native Python, `language` pythonNative, n8n 2.x). Use when the user explicitly wants Python in a…

n8n-code-tool
Auto-invoked

n8n-code-tool

Write JavaScript or Python for the n8n Custom Code Tool (@n8n/n8n-nodes-langchain.toolCode) — the AI-agent-callable tool, NOT the…

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n12d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about n8n-self-hosting.

Which coding agents can use n8n-self-hosting?
n8n-self-hosting installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.