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

Close-up view of a complex industrial gear mechanism in black and white.
Photo by Pixabay on Pexels

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.

CheckConfirmWhy it matters
RuntimeDocker and Docker Compose v2The official setup requires Compose v2
CapacityAt least 4 GB RAM and 2 vCPUStarting point for the current assistant sandbox example
StoragePersistent disk is mounted and monitoredContainers are replaceable; data must not be
NetworkA stable hostname resolves to the hostHTTPS and webhooks need a predictable endpoint
SecurityFirewall rules and exposed ports are intentionalPublic services need a narrow attack surface
RecoveryExport location and key custody are definedA 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.

  1. Change into the directory containing the Compose file and protected environment configuration.

  2. Validate the configuration:

    docker compose config
    
  3. Pull the declared images and start the services:

    docker compose pull
    docker compose up -d
    
  4. 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.

Detailed image of illuminated server racks showcasing modern technology infrastructure.
Photo by panumas nikhomkhai on Pexels
An IT professional operates a computer in a server room, managing network systems and connected devices.
Photo by panumas nikhomkhai on Pexels

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.

  1. Export workflows and credentials.
  2. Back up Postgres and preserve the encryption key.
  3. Record the deployed image reference and Compose configuration.
  4. Pull the intended image.
  5. Recreate or restart services with Compose.
  6. Inspect logs, sign in, run a test workflow, and test a webhook.
  7. 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 modeLikely causeFirst response
Workflows disappear after restart/home/node/.n8n is not persistentInspect mounts and restore from backup
Database connection errorsPostgres, credentials, or network mismatchReview configuration and logs
Webhook URL is internalPublic URL or proxy configuration is incompleteFix HTTPS routing and public URL settings
Login works but webhook failsProxy routing, certificate, or forwarded-header issueTest externally and inspect proxy logs
Credentials fail after restoreEncryption key was not preservedRestore 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.