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.
| Intent | Size hypothesis | Cash note |
|---|---|---|
| Deliberate proof | Consider Premium ~2 GB class if OS+proxy measured light | Hourly-ish experiment still bills when shut down on Premium |
| Growing production | Consider Premium 4 GB+ after measurement | Delete leftovers; Simple Backup optional |
| Native stop-compute lab | Only with disk/IP leftover discipline | Forgotten 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
- Create project, secrets, and backup directories under something like
/opt/aixvps/n8n. - Verify image UID/GID from the selected upstream before chown.
- Generate a unique Postgres password and one stable n8n encryption key.
- Store both in a password manager + off-host copy;
.envmode 600; publish only a blank.env.example.
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 --quietwithout 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.
| Symptom | Safer branch | Avoid |
|---|---|---|
| DB down / auth errors | Check volume/health; restore from proven dump | Rebuild over live data |
| Encryption key mismatch | Stop; restore key from off-host copy | Generate a new key “to fix it” |
| TLS / webhook failures | DNS/proxy/canonical URL | Open 5678 publicly as a shortcut |
| OOM / disk | Resize Premium; prune executions | Ignore and hope |
| Unexpected prepaid drain | Shut-down billing / leftover backups | Assume 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.