Self-hosted n8n workflow automation running on Cloudflare Containers, backed by Neon PostgreSQL.
Browser / Webhook
│
▼
Cloudflare Worker
│ (proxies via Durable Object)
▼
Container — n8n v2.27.3 (port 5678)
│
▼
Neon PostgreSQL (workflows, credentials, executions)
A single Cloudflare Worker receives all traffic and forwards it to the n8n container through a Durable Object. The container sleeps after 1 hour of inactivity and wakes automatically on the next request. All persistent data lives in Neon, so restarts are lossless.
- Node.js 18+
- Wrangler CLI (
npm install -g wrangler) - A Cloudflare account with Containers access
- A Neon PostgreSQL database
npm install
cp .env.example .env # fill in your values
npm run devnpx wrangler secret put DB_POSTGRESDB_HOST
npx wrangler secret put DB_POSTGRESDB_USER
npx wrangler secret put DB_POSTGRESDB_PASSWORD
npx wrangler secret put DB_POSTGRESDB_DATABASE
npx wrangler secret put N8N_ENCRYPTION_KEY # openssl rand -hex 32npm run deployWrangler will upload the Worker and register the Docker Hub image. The container provisions in a few minutes.
After the first deploy, set N8N_HOST in wrangler.toml to your actual Workers URL:
[vars]
N8N_HOST = "n8n.<your-subdomain>.workers.dev"Then redeploy:
npm run deploy| Variable | Where | Description |
|---|---|---|
N8N_HOST |
wrangler.toml [vars] |
Public hostname (used for webhooks) |
GENERIC_TIMEZONE |
wrangler.toml [vars] |
Timezone for scheduled workflows |
DB_POSTGRESDB_HOST |
Secret | Neon PostgreSQL host |
DB_POSTGRESDB_USER |
Secret | Database user |
DB_POSTGRESDB_PASSWORD |
Secret | Database password |
DB_POSTGRESDB_DATABASE |
Secret | Database name |
N8N_ENCRYPTION_KEY |
Secret | Encrypts stored credentials (keep safe) |
Container settings (in src/index.js):
| Setting | Value | Description |
|---|---|---|
instance_type |
basic |
1/4 vCPU, 1 GiB RAM, 4 GB disk |
sleepAfter |
1h |
Shuts down after 1 h of inactivity |
max_instances |
1 |
Single instance (n8n is not horizontally scalable) |
Workers Logs and container logs are enabled. View them in the Cloudflare dashboard:
Cloudflare Dashboard → Workers & Pages → n8n → Logs
Or stream live:
npx wrangler tail- Cold starts: after the container sleeps, the first request takes ~30–60 s while n8n boots and reconnects to Postgres.
- Scheduled workflows: n8n's internal scheduler only runs while the container is awake. If you need reliable cron jobs, add a Cloudflare Cron Trigger to keep the container warm during business hours.
- Webhooks during sleep: the container auto-wakes on the first webhook, but that initial request may time out. A keepalive ping avoids this.