RunbookDIY ComposeUpdated 2026-11-06

n8n on UpCloud: pinned Compose, private Postgres, and restore proof

Default to an operator-owned stack. Research did not capture an official UpCloud n8n one-click—do not invent one.

Workload before headline price — verify the plan, terms and recovery path
How to use this. Steps reflect common operator problem-handling patterns and public UpCloud flows. Follow your live Control Panel labels; discover actual OS, services, and paths on your host before production changes.

Choose Path B (blank-host Compose), Path A (only if a real image appears), or migrate existing

Default Path B: blank Ubuntu from Setup → operator-owned Compose below. Research1 captured no official UpCloud n8n one-click—do not promise one.

Path A (conditional): only if a marketplace/image landing is later evidenced—discovery-first harden/export; never invent default passwords; never paste Path B commands onto an unknown layout.

Existing install → identify/export/migrate; never a second stack on the same DB, domain, or volumes.

IntentSize hypothesisCash note
Deliberate proofConsider Premium ~2 GB class if OS+proxy measured lightHourly-ish experiment still bills when shut down on Premium
Growing productionConsider Premium 4 GB+ after measurementDelete leftovers; Simple Backup optional
Native stop-compute labOnly with disk/IP leftover disciplineForgotten Native storage bills

Path A — discovery and harden (only if image exists)

  • Inventory containers/services/ports/admin URL/version as installed.
  • Restrict admin/UI to HTTPS + auth; close accidental public 5678/DB ports.
  • Locate data directories/volumes; prove workflow JSON export + DB dump before go-live.
  • If internals are opaque, prefer Path B for production ownership.

Path B — discovery, /opt/aixvps/n8n, and stable encryption key

# scope-safe discovery examples — do not dump secrets
docker compose ls
ss -tulpn
lsblk
  1. Create project, secrets, and backup directories under something like /opt/aixvps/n8n.
  2. Verify image UID/GID from the selected upstream before chown.
  3. Generate a unique Postgres password and one stable n8n encryption key.
  4. Store both in a password manager + off-host copy; .env mode 600; publish only a blank .env.example.
Key loss. Regenerating the encryption key casually on restart/update/restore breaks credential decryption. Treat the key like production data.

Path B — one coherent Compose: private n8n, private Postgres, one proxy

At draft/implement time, pin intentionally validated n8nio/n8n, a supported PostgreSQL, and one reverse proxy (Caddy or Nginx)—no faux version pins in this outline stage prose. Requirements:

  • Private Docker network; named volumes; no public 5432.
  • n8n published only via proxy layout (container proxy or 127.0.0.1:5678).
  • Healthchecks, depends_on, restart: unless-stopped, resource bounds as appropriate.
  • DNS ready; public 80/443 only; inspect host firewall + Docker effective listeners.
  • Canonical HTTPS URL/webhook settings per current n8n docs; timezone; bounded concurrency/pruning as operator-labeled choices.

Recheck official n8n hosting/env/queue/pruning/update docs before you freeze pins in HTML.

Validate, day-two health, upgrade, and failure triage

  • docker compose config --quiet without printing secrets; up; create owner; harmless workflow; restart persistence proof.
  • Acceptance receipt: pins/digests, URL, exposure map, key location, DB health, RAM/disk before-after, first restore rehearsal date, family/plan recorded.
  • Day-two: health/logs/disk/execution growth/TLS expiry/backup freshness; prune by RPO.
  • Upgrade: control writers → current export → verify restore of final cutoff before destructive rollback.
SymptomSafer branchAvoid
DB down / auth errorsCheck volume/health; restore from proven dumpRebuild over live data
Encryption key mismatchStop; restore key from off-host copyGenerate a new key “to fix it”
TLS / webhook failuresDNS/proxy/canonical URLOpen 5678 publicly as a shortcut
OOM / diskResize Premium; prune executionsIgnore and hope
Unexpected prepaid drainShut-down billing / leftover backupsAssume pause=$0

Backup handoff (app-consistent, not snapshot-only)

On a defined cutoff: workflow JSON export + Postgres dump + encryption key backup to an independent off-host location. Optional Simple Backup / on-demand snapshots are extra layers—not substitutes. Prove restore on a non-production target before valuable automations.

Final checklist: HTTPS, key protected, concurrency bounded, independent restore proven, delete calendar if this is a trial/experiment. Full leftover billing rules live on billing / backup / cancel.