n8n Docker Hosting: From Compose to Production
n8n Docker in production: working Docker Compose setup, Sydney hosting tradeoffs, and the gotchas that broke our deployments before they break yours.
Updated May 2026. Re-audited for on-page SEO and expanded with monitoring, Kubernetes notes, FAQ schema, and authoritative outbound references.
n8n Docker is the runtime we deploy most often for production workflow automation across Australian clients. It is portable, reproducible, and gives you the control that managed offerings cannot. We have run hundreds of n8n Docker containers in production over the last three years, and most of what makes a deployment reliable comes down to a handful of decisions you make in the first hour.
At Osher Digital, we are a Brisbane-based n8n consultancy that has shipped n8n Docker deployments into healthcare, recruitment, finance, and professional services environments. This guide is the version we wish we had when we started. It covers the working configuration, the production gotchas, and the cost tradeoffs you actually face once real workflows are running. The official n8n Docker hosting documentation is the canonical reference; this is the practitioner companion.
It is aimed at developers, ops engineers, and technical decision-makers evaluating Docker as the runtime for n8n. If you are weighing whether to self-host at all, our guide on self-hosting versus n8n Cloud is the better starting point. If you have already decided on n8n Docker, keep reading.
Why Self-Host n8n with Docker
Docker has become the default runtime for n8n for three practical reasons. The first is reproducibility. Your local environment, your staging server, and your production host all run the same n8n Docker image. The differences that bite you in non-containerised deployments simply do not exist.
The second is upgrade discipline. n8n ships frequent releases, and pinning a specific image tag (rather than running latest) makes upgrades a controlled event rather than a surprise. We pin every production deployment to a known-good minor version and only roll forward after a smoke test in staging.
The third is the integration story. The official n8n Docker image works the same on a Hetzner box in Frankfurt, a DigitalOcean droplet in Sydney, an AWS ECS service in ap-southeast-2, or your laptop. That portability matters when a client wants to move data sovereignty from a US region to an Australian one without rewriting their automation.
n8n Docker Prerequisites and Hardware Requirements
For a small team running fewer than 50 workflows with light webhook traffic, n8n Docker is comfortable on 2 vCPU and 2 GB of RAM. We size most starter deployments at 2 vCPU and 4 GB, because n8n’s Node.js process can spike during heavy executions and an OOM kill is the single most common cause of mysterious “n8n stopped responding” tickets.
For mid-sized teams running hundreds of workflows or processing structured documents, plan for 4 vCPU and 8 GB. Once you cross into thousands of executions per day, queue mode (with separate worker containers) becomes essential. We cover queue mode briefly below; if you are already there, our n8n configuration settings guide walks through the environment variables.
You will also need:
- Docker Engine 24.0 or newer, plus Docker Compose v2 (see Docker Compose documentation).
- A domain name pointed at your server’s IPv4 address.
- A PostgreSQL database for any deployment beyond the simplest test.
- SSH access and a reverse proxy (we use Caddy or Traefik).
Quick Start: n8n Docker Setup
The fastest way to confirm n8n Docker runs on your host is a single docker run command. This is fine for evaluation. It is not how you should run production. We will replace it with a Compose file in the next section. The image lives on Docker Hub at n8nio/n8n and on the official registry at docker.n8n.io/n8nio/n8n; both ship the same software but the official registry is rate-limit-friendly and updates faster.
docker volume create n8n_data
docker run -d \
--name n8n \
--restart unless-stopped \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
-e GENERIC_TIMEZONE=Australia/Brisbane \
-e TZ=Australia/Brisbane \
-e N8N_HOST=localhost \
-e WEBHOOK_URL=http://localhost:5678/ \
docker.n8n.io/n8nio/n8n:1.95.0
Visit http://localhost:5678, complete the owner setup, and you have a working n8n Docker container. Note that we pin the image tag (1.95.0) rather than using latest. This is the single most important habit for n8n Docker hosting. Every production incident we have triaged that started with “n8n stopped working overnight” came down to an unpinned image being silently upgraded.
Production-Grade n8n Docker Compose Setup
For anything beyond a sandbox, run n8n Docker Compose with a managed PostgreSQL database and a reverse proxy that terminates TLS. Here is the configuration we use as a starting point for every production deployment.
version: "3.8"
services:
postgres:
image: postgres:16
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:1.95.0
restart: always
depends_on:
postgres:
condition: service_healthy
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: ${N8N_HOST}
N8N_PROTOCOL: https
N8N_PORT: 5678
WEBHOOK_URL: https://${N8N_HOST}/
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
GENERIC_TIMEZONE: Australia/Brisbane
TZ: Australia/Brisbane
N8N_RUNNERS_ENABLED: "true"
N8N_DIAGNOSTICS_ENABLED: "false"
volumes:
- n8n_data:/home/node/.n8n
ports:
- "127.0.0.1:5678:5678"
volumes:
postgres_data:
n8n_data:
Two details matter more than they look. The N8N_ENCRYPTION_KEY is what n8n uses to encrypt credentials in the database. If you lose it, you lose every stored credential and have to re-authenticate every workflow. We back this up the moment we generate it, store it in a password manager, and treat it as more sensitive than the database itself.
The second is binding the n8n port to 127.0.0.1 rather than 0.0.0.0. This means the n8n Docker container is only reachable from the host machine, and the reverse proxy (running on the same host) handles all external traffic. It closes off a class of accidental exposure that has caught teams who relied on a firewall but did not lock down the container port.
n8n Docker Configuration for Production
n8n Docker is configured almost entirely through environment variables. The defaults are fine for evaluation and dangerous in production. The variables that we always set on a new deployment include the encryption key, the database connection, the public host and webhook URL, and the timezone. Beyond those, a few production switches are worth knowing.
N8N_RUNNERS_ENABLED moves code-node execution into a separate runner process. This is the new default in 1.x and reduces the blast radius of a misbehaving code node. Leave it on.
EXECUTIONS_DATA_PRUNE and EXECUTIONS_DATA_MAX_AGE control automatic execution log cleanup. Without them, the n8n database grows without bound. We set EXECUTIONS_DATA_PRUNE=true and EXECUTIONS_DATA_MAX_AGE=336 (14 days in hours) for most clients, longer if compliance demands it.
N8N_DIAGNOSTICS_ENABLED controls anonymous usage telemetry. We turn it off by default for clients in regulated industries, on by default elsewhere.
N8N_PUSH_BACKEND selects between long-polling and WebSocket for the editor’s live updates. WebSocket is the default and works fine through Caddy and Traefik. Some corporate proxies still strip WebSocket upgrades, in which case set this to sse.
For a complete reference, our n8n configuration guide lists every variable we tune for production n8n Docker deployments.
Database Selection: SQLite vs PostgreSQL
n8n defaults to SQLite. SQLite is fine for a single-user instance running a handful of workflows. It is not fine once your deployment matters. Every production failure mode we have seen on SQLite traces back to file-locking under concurrent webhooks or a corrupted database after an unclean shutdown.
We move every client to PostgreSQL on day one. The migration is straightforward: stand up a Postgres instance, configure the DB_* variables shown above, and start n8n against the new database. n8n creates its schema on first run. If you already have data in SQLite, n8n’s documentation has a working migration script; for clients with substantial workflow history, we typically run a fresh export and import rather than the in-place migration.
The exception is when you are running n8n purely for personal use on a low-power machine. SQLite is genuinely lighter and the failure modes do not bite at single-user scale. If a workflow break would cost you a real customer, use Postgres.
Securing n8n with HTTPS and a Reverse Proxy
Never expose the n8n Docker container directly on port 5678. Run a reverse proxy in front of it. The proxy terminates TLS, manages certificates, and lets you put authentication or rate limiting in front of webhooks if you need to. We use Caddy on most deployments because the Caddyfile is the shortest path from “no proxy” to “automatic HTTPS with Let’s Encrypt”.
n8n.your-domain.com.au {
reverse_proxy 127.0.0.1:5678
encode gzip
header {
Strict-Transport-Security "max-age=31536000;"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "no-referrer-when-downgrade"
}
}
Three lines of Caddyfile and you have HTTPS, automatic certificate renewal, gzip compression, and the security headers that automated scanners flag if they are missing. Restart Caddy and the certificate provisions in seconds.
If you need authentication in front of n8n’s editor (n8n’s own auth covers most cases, but corporate clients sometimes want SSO at the proxy layer), Caddy’s forward-auth directive integrates cleanly with Authentik or Authelia. We have shipped this pattern for clients with strict access control requirements.
n8n Docker Backups, Updates, and Recovery
A backup strategy for n8n Docker has three components. You back up the Postgres database, the encryption key, and the workflow JSON exports. Lose the database and you lose execution history. Lose the encryption key and the database is useless because every stored credential is unreadable. Lose the workflow exports and you have to rebuild from memory.
Our standard backup pattern is a nightly pg_dump piped to gzip and rsynced to off-host storage (we use Backblaze B2 for most clients, with the bucket region set to ap-southeast-2 where available). The encryption key lives in 1Password. The workflow JSON exports are pulled via the n8n API on a weekly cron and committed to a private git repo.
Updates follow a strict pattern. Read the n8n release notes. Update the staging Compose file. Run docker compose up -d. Smoke test the dozen workflows that matter most. If staging is healthy for 48 hours, repeat in production. We have rolled back exactly twice in three years, both times due to credential schema migrations that needed a one-line config change to clear up. Knowing which version was healthy made the rollback minutes rather than hours.
Monitoring n8n Docker in Production
An n8n Docker deployment that runs unmonitored is one credential expiry away from a silent outage. The pattern we use across clients has three layers: container health, application health, and workflow health.
Container health. Add a Docker healthcheck to both the n8n and Postgres services in your Compose file. The Postgres healthcheck above (pg_isready) is the right shape; for n8n itself, a simple HTTP probe against /healthz works:
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
Application health. n8n exposes Prometheus metrics when you set N8N_METRICS=true. We scrape these into Grafana or BetterStack with alerts on failed executions per minute, queue depth (if running queue mode), and event-loop lag. The Prometheus exporter is the lightest way to get production-grade observability without third-party agents inside the container.
Workflow health. Every business-critical workflow has a “canary” execution that runs every 5 to 15 minutes and reports success to an external watchdog (we use BetterStack or a simple uptime monitor). If three canary runs fail consecutively, the watchdog pages on-call. This catches the failure modes that container and application metrics miss: a webhook URL that no longer points where you think, a third-party API that has changed its response shape, or a credential that has silently expired.
For clients running queue mode at scale, we also push n8n logs to Loki via the Docker logging driver and alert on specific error patterns rather than just log volume. This has caught more than one production issue that the metrics alone did not surface.
Australian Hosting Options and AUD Costs
For Australian clients, where the n8n Docker container actually runs matters for two reasons: webhook latency to local services and data sovereignty under the Australian Privacy Principles. The hosts we recommend most often, with rough monthly AUD costs for a 2 vCPU / 4 GB box suitable for production:
- DigitalOcean Sydney (SYD1). Around $35 AUD per month for a basic 2 vCPU droplet. Reliable, well-documented, and the closest thing to a default choice.
- Vultr Sydney. Around $30 AUD per month for an equivalent instance. Slightly cheaper than DigitalOcean with comparable performance.
- Linode (Akamai) Melbourne. Around $40 AUD per month. Worth considering if you want a Melbourne presence rather than Sydney.
- Hetzner Cloud Frankfurt or Ashburn. Around $15 AUD per month, but data leaves Australia. Suitable for non-sensitive workloads where price dominates.
- AWS Lightsail Sydney. Around $35 to $80 AUD per month depending on plan. Useful when the rest of the stack is already on AWS in ap-southeast-2.
For clients handling personal information under the Privacy Act 1988, we keep both n8n and Postgres in an Australian region by default. If you are processing health records or financial data, this is not a preference, it is a compliance position. Book a call if you need help mapping your specific compliance posture to a hosting choice.
n8n Docker on Kubernetes
Most n8n Docker deployments do not belong on Kubernetes. A single VPS with Docker Compose is operationally simpler, costs less, and handles the load profile of almost every business workflow we have ever shipped. Kubernetes earns its place in three specific cases.
The first is when n8n is one component of a larger Kubernetes platform you already operate. If your team is running EKS, GKE, or AKS in production for other workloads, adding n8n via the community n8n Helm chart is straightforward and gives you the same deployment, scaling, and secrets management patterns you use elsewhere.
The second is queue mode at significant scale. If you are processing hundreds of thousands of executions per day with bursty traffic, Kubernetes HPA against custom Prometheus metrics gives you cleaner autoscaling of worker pods than Docker Compose can.
The third is when compliance demands network policies, pod security standards, or audit logging that Docker Compose cannot provide cleanly. A few of our regulated-industry clients sit here.
For everyone else, Docker Compose on a Sydney VPS is the right answer. If you are unsure which side of the line you sit on, the question to ask is: would I run this workload on Kubernetes if it were not n8n? If the answer is no, Compose is the choice.
When n8n Docker Self-Hosting Is Not the Right Choice
We self-host most clients. We do not self-host all of them. n8n Docker on a VPS is the wrong choice when:
You do not have ops capacity. Self-hosted n8n needs someone who can read the logs, apply updates, and respond when the box runs out of disk at 2am. If that person does not exist on your team, n8n Cloud is cheaper than the on-call service you would otherwise have to retain.
Your workload is genuinely small. If you have ten workflows that fire once a day, n8n Cloud’s starter tier is around $30 AUD per month, which is competitive with self-hosting once you factor in the time to set it up and keep it patched.
You need n8n’s enterprise features urgently. SSO, log streaming, and external secrets are on n8n Cloud’s higher tiers and on the self-hosted enterprise license. If you need these on day one, the licensing path may be quicker than the self-hosted equivalent.
For everyone else (which is most production-scale clients) n8n Docker on a Sydney VPS is the configuration we ship most often. It is the best balance of cost, control, and data sovereignty for Australian operations.
Troubleshooting Common Production Issues
The same issues come up across n8n Docker deployments. Here is how we resolve them.
Webhook 502s after deploy. Almost always the reverse proxy pointing at a stale container ID. Restart the proxy. If it persists, check that WEBHOOK_URL matches the public domain.
“Stuck” executions. If a workflow shows running for hours and never completes, you are probably hitting the Node.js event loop being blocked by a synchronous code node. Enable the runner process (N8N_RUNNERS_ENABLED=true) so code nodes execute in their own subprocess.
OOM kills overnight. Set Docker memory limits explicitly (mem_limit: 4g), tune execution pruning, and confirm there are no workflows accumulating large arrays in code nodes. Most OOM tickets we triage trace back to a single workflow concatenating 100,000 rows into memory.
Disk full from execution data. Postgres stores every successful execution body by default. Pruning is the cure. Confirm EXECUTIONS_DATA_PRUNE=true is set and rebuild your indexes if the table has grown to tens of GB.
Editor slow with many nodes. Browser-side performance, not server. Run the editor in Chrome rather than Firefox if you have hundreds of nodes in a single workflow, or split the workflow into sub-workflows.
Scaling n8n Docker Beyond a Single Container
A single n8n Docker container handles a surprising amount of traffic. We have clients running 50,000+ executions per day on a single 4 vCPU container with Postgres on the same host. The point at which you outgrow a single container is when execution latency starts climbing because the main process is too busy to schedule new work.
The answer is queue mode. You run an n8n main process for the editor and webhook routing, plus N worker containers that pick executions off a Redis queue. This horizontal pattern lets you scale workers independently and survives a single worker crash without dropping work in flight. We have run this pattern for clients processing several hundred thousand executions per day.
Queue mode is overkill for most teams. It introduces Redis as a dependency and the operational footprint roughly doubles. Do not reach for it unless you have measured a single-container bottleneck. If you think you might be there, our team can help you test the threshold properly. We have also written about production self-hosting tradeoffs in more depth.
Frequently Asked Questions
How do I install n8n with Docker?
Pull the official n8n Docker image (docker.n8n.io/n8nio/n8n), pin it to a specific version tag, mount a volume for persistent state, and run it with the environment variables for your timezone, host, and webhook URL. For anything beyond evaluation, run it via Docker Compose with PostgreSQL and a reverse proxy. The Compose file in the production setup section above is the configuration we use as a starting point.
Which n8n Docker image should I use?
Use the official n8n Docker image at docker.n8n.io/n8nio/n8n, pinned to a specific version tag rather than latest. The community image at n8nio/n8n on Docker Hub is the same software but the official registry is rate-limit-friendly and ships faster. Pinning the version is the single most important habit; unpinned images get silently upgraded and break workflows in unpredictable ways.
How much does it cost to host n8n Docker in Australia?
For a production-suitable 2 vCPU and 4 GB box in a Sydney or Melbourne region, expect $30 to $80 AUD per month depending on the provider. Vultr Sydney and DigitalOcean Sydney sit at the cheaper end; AWS Lightsail and Linode Melbourne are slightly higher. Add a few dollars per month for off-host backup storage on Backblaze B2 or AWS S3.
Can I run n8n Docker on Windows or Mac?
Yes, Docker Desktop on Windows and Mac runs the same n8n Docker image. We use this for local development. We do not recommend it for production. Production n8n belongs on a Linux host, ideally a small VPS, where the runtime characteristics match the official image’s testing environment. Docker Desktop also tends to consume more RAM on the developer machine than is comfortable for daily use.
Do I need PostgreSQL or can I use SQLite?
SQLite is fine for evaluation and single-user setups. Move to PostgreSQL the moment your n8n Docker deployment matters to a real customer or business process. The failure modes of SQLite under concurrent webhook load (file locking, partial writes, corruption after unclean shutdown) are real and we have triaged each of them in client incidents. PostgreSQL adds an hour of setup and removes a class of failure entirely.
How do I update n8n running in Docker?
Update the image tag in your Compose file to the new version, run docker compose pull, then docker compose up -d. n8n applies any database migrations automatically on startup. Always test the new version in staging first and read the release notes for breaking changes. We back up the Postgres database before any minor version upgrade and the encryption key separately because losing it is unrecoverable.
How do I enable HTTPS for n8n in Docker?
Run a reverse proxy in front of n8n. Caddy is the shortest path: a three-line Caddyfile gets you automatic Let’s Encrypt certificates, gzip, and standard security headers. Traefik works equally well if you prefer label-driven configuration. Do not try to configure n8n itself to terminate TLS in production; the proxy approach is more flexible and easier to operate.
How do I monitor n8n Docker in production?
Three layers. Container health via Docker healthchecks on n8n and Postgres. Application health via the Prometheus metrics endpoint (N8N_METRICS=true) scraped into Grafana or BetterStack. Workflow health via canary executions that run every 5-15 minutes and report success to an external watchdog. The third layer catches failure modes (expired credentials, changed third-party APIs, broken webhook routes) that infrastructure monitoring alone will miss.
Is self-hosted n8n Docker suitable for Australian Privacy Act compliance?
Self-hosting n8n Docker in an Australian region (DigitalOcean Sydney, Vultr Sydney, AWS ap-southeast-2) gives you control over data location that managed offerings cannot match. That makes it a strong fit for compliance with the Australian Privacy Principles, particularly APP 8 (cross-border disclosure) and industry-specific regimes like APRA CPS 234. Compliance is more than location, of course; you also need access controls, encryption at rest, audit logs, and a documented incident response. We help clients map these requirements to a deployment shape as part of our n8n consulting work.
If you want help shipping a production-grade n8n Docker deployment, or if you have one running and want a second pair of eyes on the configuration, get in touch with our team. We are based in Brisbane and run n8n Docker for businesses across Australia.
Jump to a section
Ready to streamline your operations?
Get in touch for a free consultation to see how we can streamline your operations and increase your productivity.