How to self-host n8n on Ownkube

Deploy the official n8nio/n8n image on Ownkube with a managed Postgres database, working webhooks, and automatic TLS on your own domain.

Ownkube team | | How-To | 5 min

n8n is a workflow automation tool worth self-hosting the moment you have more than a couple of workflows, since the hosted cloud plans price by execution and self-hosting removes that ceiling. This walks through deploying the official n8nio/n8n image on Ownkube with a Postgres database behind it, correct webhook URLs, and TLS on a real domain.

TL;DR

  • n8n defaults to a bundled SQLite database, which does not hold up well under concurrent workflow executions. Point it at Postgres with the DB_TYPE=postgresdb env vars instead.
  • Deploy the official n8nio/n8n image, attach a managed Postgres database box, and set N8N_HOST, N8N_PROTOCOL, and WEBHOOK_URL to your real domain before you build any workflow that uses a webhook trigger.
  • Mount a persistent volume at /home/node/.n8n so encryption keys and local credentials survive restarts.
  • Ownkube issues TLS automatically on your custom domain, which matters for n8n since most webhook-based integrations (Stripe, GitHub, Slack) refuse plain HTTP callback URLs.
  • A database box starts at $4/month plus storage, and the app itself can sit on a small reserved box or run metered depending on how often workflows fire.

What you need before you start

  • The image reference n8nio/n8n:latest, or a pinned version tag if you want reproducible upgrades.
  • A domain or subdomain to point at the app. Webhook-triggered workflows need a stable, real URL, not the preview hostname you get before attaching a domain.
  • A generated encryption key if you want to set it explicitly rather than let n8n generate one on first boot (recommended, since regenerating it later invalidates saved credentials).

1. Create a managed Postgres database

n8n supports Postgres as its production-grade database option, and it is the one to use for anything beyond a single-user test instance. Create a database box on Ownkube (from $4/month plus storage at $0.15/GB/month) and note the host, port, database name, user, and password.

2. Deploy the n8n image

Create the app from n8nio/n8n:latest, or start from this Dockerfile if you want to pin a version:

FROM n8nio/n8n:1.60.1

Point the app at port 5678, which is what the image listens on by default.

3. Set the environment variables

# Database
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=<your-postgres-host>
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=<your-postgres-user>
DB_POSTGRESDB_PASSWORD=<your-postgres-password>

# Host and webhooks
N8N_HOST=automate.example.com
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://automate.example.com/

# Security
N8N_ENCRYPTION_KEY=<a-long-random-string>
GENERIC_TIMEZONE=UTC

Set N8N_HOST, N8N_PROTOCOL, and WEBHOOK_URL to your real domain before you build anything that depends on an inbound webhook. n8n bakes the webhook base URL into every workflow’s trigger node, so changing it later means editing each affected workflow rather than a single config change.

4. Attach persistent storage for credentials and local files

Mount a persistent volume at /home/node/.n8n. This is where n8n stores its SQLite metadata (used for some internal state even in Postgres mode), the encryption key if you let it self-generate, and any binary data written to local storage. Without a persistent volume here, a redeploy can regenerate the encryption key and invalidate every saved credential in your workflows.

5. Attach your domain and verify webhooks

Point your domain’s DNS at the app’s Ownkube hostname and attach the custom domain in the dashboard. TLS is issued automatically once DNS resolves. Confirm the app is reachable and that a test webhook round-trips correctly:

curl -I https://automate.example.com

# From n8n's UI, use the "Listen for test event" button on a webhook
# trigger node, then send a test request to confirm the URL is public
# and TLS-terminated correctly.
curl -X POST https://automate.example.com/webhook-test/<path>

Most third-party services that trigger n8n workflows (Stripe, GitHub, Slack, Typeform) require HTTPS callback URLs and reject plain HTTP, so this step matters more for n8n than for a typical web app.

Sizing the deployment

A handful of scheduled workflows that run occasionally is a light workload and fits comfortably on metered pricing, where CPU and memory bill on actual per-minute use, so idle time between runs costs almost nothing. A busier setup with many active webhook triggers and frequent executions runs closer to constant load, which is a better fit for a flat Spark or Core box so the price does not move with execution volume. You choose per deployment and can switch later without redeploying the underlying image.

If this instance eventually needs to move off shared infrastructure, for example because a workflow now touches data with residency requirements, the same n8nio/n8n image and Dockerfile run unchanged in your own AWS account under Ownkube’s own-cloud option, with the same logs and health checks attached. No rewrite, just a different compute target. For a broader look at self-hosted automation platforms next to managed alternatives, see our comparison of Railway, Render, and Northflank.

FAQ

Does n8n need Postgres, or does SQLite work?

n8n ships with SQLite by default and it works for light single-user use, but the project recommends Postgres for anything with concurrent executions or production reliability expectations. Set DB_TYPE=postgresdb and the matching DB_POSTGRESDB_* variables to use it.

Why do my webhook URLs return the wrong host?

WEBHOOK_URL (and N8N_HOST/N8N_PROTOCOL) must match the real public domain before you create webhook-triggered workflows. If you change the domain later, existing webhook trigger nodes keep the old URL baked in and need to be recreated or manually updated.

What happens if I lose the encryption key?

N8N_ENCRYPTION_KEY decrypts stored credentials. If it changes or is lost, every saved credential in existing workflows stops working and needs to be re-entered. Set it explicitly as an environment variable rather than letting n8n generate one you have not saved.

Can I run n8n without a persistent volume?

You can, but a redeploy resets /home/node/.n8n, which can regenerate the encryption key and lose local state. Mount a persistent volume there for anything beyond a throwaway test instance.

What does this cost to run?

A Postgres database box starts at $4/month plus storage. The n8n app itself can run metered for light, occasional workflow use or on a Spark box (from $5/month) for steadier automation.

Where Ownkube fits

n8n’s official image needs a real database and a stable public URL to be reliable, and Ownkube Compute covers both without a cloud account to configure first. Deploy the image, attach managed Postgres, mount the config volume, and point a domain at it for TLS-backed webhooks. Deploy your first app.

More posts