# 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 a stable public address.

- **Published:** 2026-08-29
- **Author:** Abhishek Jaiswal
- **Category:** How-To
- **Tags:** n8n, self-hosting, automation, deploy, tutorial
- **Canonical URL:** https://ownkube.io/blog/deploy-n8n
- **Cover:** https://ownkube.io/blog/deploy-n8n.png

---
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 stable public address.

**TL;DR**

- n8n defaults to a bundled SQLite database, which does not hold up well under concurrent workflow executions. Point it at [Postgres](https://www.postgresql.org/docs/) with the `DB_TYPE=postgresdb` env vars instead.
- Deploy the official `n8nio/n8n` image, attach a [managed Postgres database](/blog/add-managed-postgres-database) box, and set `N8N_HOST`, `N8N_PROTOCOL`, and `WEBHOOK_URL` to the app's public address before you build any workflow that uses a webhook trigger.
- Set `N8N_ENCRYPTION_KEY` yourself so saved credentials survive restarts and redeploys.
- Every Ownkube app gets an `ownkube.app` address with automatic TLS, 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 subdomain for the app on `ownkube.app`, for example `automate-yourteam.ownkube.app`. Webhook-triggered workflows need a stable URL, so pick it before you build any.
- A generated encryption key, set explicitly rather than letting n8n generate one on first boot, since a regenerated key 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.25/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:

```dockerfile
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

```bash
# 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-yourteam.ownkube.app
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://automate-yourteam.ownkube.app/

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

Set `N8N_HOST`, `N8N_PROTOCOL`, and `WEBHOOK_URL` to the app's public address before you build anything that depends on an inbound webhook. n8n bakes the [webhook base URL](https://docs.n8n.io/) into every workflow's trigger node, so changing it later means editing each affected workflow rather than a single config change.

## 4. Keep the app stateless

With `DB_TYPE=postgresdb`, workflows, executions, and credentials live in Postgres, not on the container's disk. The one thing n8n would otherwise keep in `/home/node/.n8n` is the encryption key it generates on first boot, and a redeploy would lose it. Setting `N8N_ENCRYPTION_KEY` explicitly (step 3) removes that dependency, so the app can restart or redeploy without invalidating any saved credential.

## 5. Verify webhooks

The app's `ownkube.app` address serves HTTPS from the first deploy, with no DNS to set up. Confirm the app is reachable and that a test webhook round-trips correctly:

```bash
curl -I https://automate-yourteam.ownkube.app

# 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-yourteam.ownkube.app/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](/blog/prepaid-wallet-no-surprise-bill), billed per minute. 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](/blog/railway-vs-render-vs-northflank-2026).

## 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](https://docs.n8n.io/hosting/configuration/environment-variables/database/) 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 app's public address before you create webhook-triggered workflows. If you change the address 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?

Yes, as long as it uses Postgres and `N8N_ENCRYPTION_KEY` is set explicitly. Without the key, a redeploy resets `/home/node/.n8n` and n8n generates a new one, which breaks every saved credential.

### 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, set the encryption key, and your webhooks get an HTTPS address from the first deploy. See [Ownkube pricing](/pricing) for the per-minute wallet model, from $5 a month. [Deploy your first app](https://app.ownkube.io/login).