Automation guide
Self-Host n8n with Docker Compose: A Production-Ready Setup
Deploy n8n with Docker Compose, Postgres, durable storage, HTTPS, backups, and a rollback plan that protects production workflows.
Published and reviewed by OpenAlt · September 22, 2026

Treat self-hosting as an operating system, not a one-command install. Docker Compose v2 is required, and n8n’s current assistant sandbox example specifies at least 4 GB RAM and 2 vCPU. n8n’s Docker Compose guide
Table of Contents
This sequence takes you from host readiness to a verified, recoverable deployment.
- Why this stack?
- Preflight checklist
- Files and secrets
- Start the stack
- Reverse proxy and webhooks
- Verify the deployment
- Back up workflows, credentials, and the encryption key
- Upgrade, rollback, and failure modes
- Next step
- Frequently Asked Questions
Why this stack?
Use Compose with persistent n8n data and Postgres when workflows matter. A single container can support learning, but it is not a durable operating plan.
Compose keeps the application, database, volumes, and restart behavior in one reviewable definition. Postgres separates workflow data from an ephemeral container filesystem, while persistent storage protects n8n’s application directory when containers are replaced. A reverse proxy provides the public HTTPS endpoint needed for browser access and webhook delivery. Workflow exports, database backups, and the encryption key provide recovery options beyond the live instance.
n8n’s official hosting examples include Postgres and persist /home/node/.n8n, the application data path that must survive container replacement. Review the official Postgres Compose example before adapting the stack to your host.
Preflight checklist
Confirm the host, DNS, storage, security, and recovery plan before starting containers.
| Check | Confirm | Why it matters |
|---|---|---|
| Runtime | Docker and Docker Compose v2 | The official setup requires Compose v2 |
| Capacity | At least 4 GB RAM and 2 vCPU | Starting point for the current assistant sandbox example |
| Storage | Persistent disk is mounted and monitored | Containers are replaceable; data must not be |
| Network | A stable hostname resolves to the host | HTTPS and webhooks need a predictable endpoint |
| Security | Firewall rules and exposed ports are intentional | Public services need a narrow attack surface |
| Recovery | Export location and key custody are defined | A running instance is not a backup |
The capacity figures are a starting point, not a universal sizing promise. Workflow size, execution history, concurrency, and other services can change the real requirement.
Files and secrets
Create a dedicated project directory containing:
- The Compose file.
- A restricted environment or secret file.
- A backup directory on persistent storage.
- Any reverse-proxy configuration maintained separately from application data.
Start from n8n’s official Postgres example. Keep the persistent mount for /home/node/.n8n, configure Postgres persistence, and document which host paths or named volumes hold each dataset.
Treat the n8n encryption key as recovery-critical secret material. Store it through protected secret management or in a narrowly restricted file. Never commit it to Git, paste it into tickets, or expose it in shell history.
Before launch, review authentication, TLS, network exposure, credentials, and access control. Read n8n’s security guidance.
Start the stack
Start from the project directory and inspect the rendered configuration before making the service public.
-
Change into the directory containing the Compose file and protected environment configuration.
-
Validate the configuration:
docker compose config -
Pull the declared images and start the services:
docker compose pull docker compose up -d -
Inspect service state and recent n8n logs:
docker compose ps docker compose logs --tail=100 n8n
A running container is not proof of a complete deployment. Confirm that Postgres is healthy, n8n stays up, volumes are attached, and logs show no connection, permission, or configuration errors.


Reverse proxy and webhooks
Put n8n behind a correctly configured HTTPS reverse proxy before relying on external webhooks. The proxy must route the public hostname to n8n and preserve the information n8n needs to construct public callback URLs.
Verify that:
- The hostname resolves to the intended host.
- The proxy presents a valid certificate.
- Requests reach the n8n service.
- Generated webhook URLs use the public HTTPS address, not an internal container address.
Keep the database and internal service ports private unless there is a deliberate reason to expose them. Apply authentication and network controls at the appropriate layers.
Test one representative workflow that receives an external event. Confirm that the event reaches n8n, the workflow executes, and the destination system receives the expected result. A successful browser login does not prove webhook routing.
Verify the deployment
A durable deployment is verified when the service, database, persistence, HTTPS endpoint, and workflow execution work together.
Run these checks from the project directory:
docker compose config
docker compose ps
docker compose logs --tail=100 n8n
docker compose logs --tail=100 postgres
docker compose exec n8n n8n --help
Then open the HTTPS hostname and sign in. Create or update a harmless test workflow, trigger it manually and through one external webhook, and restart the stack:
docker compose restart
Confirm that the workflow, credentials, and execution history remain available. Confirm that the webhook still uses the public HTTPS address after restart. If configuration disappears, the storage model is not suitable for durable use.
Back up workflows, credentials, and the encryption key
Back up workflows, credentials, Postgres data, and the n8n encryption key. Exporting only workflows is not enough for a recoverable instance.
Use n8n’s CLI export commands inside the running container and write the output to protected backup storage:
docker compose exec n8n n8n export:workflow --all --output=/backup/workflows.json
docker compose exec n8n n8n export:credentials --all --output=/backup/credentials.json
Protect credential exports as sensitive data. Preserve the encryption key with the recovery procedure, but not in the same casually accessible location as the exports. The matching key is required for encrypted credentials to remain usable after restoration.
Maintain a database backup process appropriate to the Postgres deployment. Periodically restore a backup in an isolated test environment and confirm that workflows, credentials, and execution behavior are usable. Follow the official backup and export commands.
Upgrade, rollback, and failure modes
Upgrade deliberately: capture backups, record the current image tag, pull the intended image, start the stack, and verify workflows before considering the change complete.
- Export workflows and credentials.
- Back up Postgres and preserve the encryption key.
- Record the deployed image reference and Compose configuration.
- Pull the intended image.
- Recreate or restart services with Compose.
- Inspect logs, sign in, run a test workflow, and test a webhook.
- Keep the previous image reference and backups until verification is complete.
Never use docker compose down -v as routine troubleshooting. Removing volumes can destroy the persistent data that makes recovery possible.
| Failure mode | Likely cause | First response |
|---|---|---|
| Workflows disappear after restart | /home/node/.n8n is not persistent | Inspect mounts and restore from backup |
| Database connection errors | Postgres, credentials, or network mismatch | Review configuration and logs |
| Webhook URL is internal | Public URL or proxy configuration is incomplete | Fix HTTPS routing and public URL settings |
| Login works but webhook fails | Proxy routing, certificate, or forwarded-header issue | Test externally and inspect proxy logs |
| Credentials fail after restore | Encryption key was not preserved | Restore with the original key and validated backup |
Security and recovery remain ongoing responsibilities. Keep access controls, secret handling, exposed ports, and backup procedures aligned with n8n’s published guidance.
Next step
Choose self-hosted n8n when you are prepared to operate storage, security, backups, updates, and webhook availability as part of the automation system.
After verification, inspect OpenAlt’s n8n profile and browse the automation directory to compare difficulty, maintenance requirements, and alternatives before a larger migration.
Frequently Asked Questions
Is self-hosted n8n free?
Self-hosting can remove the SaaS hosting dependency, but it is not operationally free. You still manage compute, storage, networking, HTTPS, security, backups, upgrades, and recovery. The tradeoff is control versus maintenance responsibility.
Does n8n need Postgres?
Not for every experiment, but Postgres is the sensible choice when workflows matter and the instance must be durable. n8n’s official hosting examples include a Postgres Compose configuration.
How much RAM does n8n need?
The current assistant sandbox example in n8n’s official Compose guide calls for at least 4 GB of RAM and 2 vCPU. Treat that as a starting point; actual requirements depend on workflow complexity and workload.
What must be backed up?
Back up workflows, credentials, Postgres data, and the n8n encryption key. Keep credential exports protected, and test restoration rather than assuming a successful export proves recoverability.
How do I know the deployment is recoverable?
Restart the stack, verify that workflows, credentials, and history remain available, and restore a backup in an isolated test environment. A backup is useful only when the original key and exported or database data can be used together.