Running n8n on your own infrastructure gives you direct control over workflow data, credentials, network access, and upgrade timing. This n8n self hosting setup guide walks through a practical Docker Compose deployment, from choosing a server to backing up and updating it. You will build a reliable foundation rather than simply start a container and hope it stays available.
Self-hosting is not automatically cheaper or safer: you take on maintenance, security, and recovery responsibilities. But for teams with suitable technical capacity, a well-planned deployment can reduce recurring platform costs and keep sensitive information within an environment you manage.
1. Plan Your n8n Self Hosting Setup Before Installing
Start by deciding where the service will run and who needs to reach it. A local development machine is useful for testing workflows, but it is not a dependable production host if it sleeps, changes networks, or is switched off. A small virtual private server, an existing Linux host, or a managed machine in your organization’s network can provide more consistent availability. Choose based on expected workload, data sensitivity, and the people available to maintain it—not on a promised one-size-fits-all server size.
A modest deployment can begin with one n8n container and a PostgreSQL database container on the same host. PostgreSQL keeps workflow and execution records in a database designed for persistent application data; Docker volumes keep database files and n8n configuration across container replacement. SQLite can suit experimentation, but PostgreSQL is a stronger default for a maintained installation. The n8n self hosting setup should also have enough disk space for execution history, database growth, logs, and backups.
List the integrations your workflows require before opening network access. For example, a workflow that receives a webhook from a CRM needs a publicly reachable HTTPS endpoint. A workflow that only polls an internal API may not need an inbound public route at all. Note whether integrations require fixed outbound IP addresses, private network access, or specific callback URLs. This helps you make DNS and firewall decisions before workflows depend on them.
Plan the service’s address and identity. A domain such as automation.example.com can point to the host, while a reverse proxy handles HTTPS certificates and forwards requests to n8n. Keep the n8n editor behind authentication and, when practical, a VPN or IP allowlist. Do not expose the database port publicly. A local n8n server can be restricted to a private network for development, but public webhooks require a reachable HTTPS endpoint and a correctly configured webhook base URL.
Decide how much operational responsibility your team can support. You will need an owner for updates, security reviews, backup checks, and incident response. Create a short runbook that records the server address, DNS provider, Docker Compose project location, volume names, backup destination, and recovery steps. Store passwords and encryption keys in a secure password manager, not in that runbook or source control.
Finally, estimate costs as a range rather than assuming self-hosting is free. Compare the host, storage, backups, monitoring, and engineering time with the subscription or usage costs of a hosted option. If the deployment handles business-critical processes, include the value of recovery testing and maintenance. The right design is one your team can operate consistently, not merely the lowest-cost server that starts successfully.
2. Prepare Docker Compose n8n Files and Persistent Storage
Install Docker Engine and the Docker Compose plugin on a supported Linux host, then confirm both commands work with docker --version and docker compose version. Use the official Docker Compose documentation for platform-specific installation steps. Create a dedicated project directory, such as /opt/n8n, and restrict access to it. Keeping the deployment files together makes updates and recovery easier to understand.
The following example defines n8n and PostgreSQL as services and gives each persistent storage. It is a starting point, not a complete production security policy. Replace placeholder values, use a current supported image version, and check n8n’s deployment guidance before adopting configuration changes. Pinning a tested version helps prevent an unplanned update from changing behavior during a restart.
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
n8n:
image: docker.n8n.io/n8nio/n8n:1.XX.X
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "127.0.0.1:5678:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: ${N8N_HOST}
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_HOST}/
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
TZ: ${GENERIC_TIMEZONE}
volumes:
- n8n_data:/home/node/.n8n
volumes:
postgres_data:
n8n_data:Replace 1.XX.X with a real, tested n8n version before starting the stack. Set the host name to the public domain used by the reverse proxy. The example binds port 5678 to the host’s loopback interface, so an on-host proxy can reach it without making that port directly available on every network interface. If your proxy runs in another container, use a shared Docker network and avoid publishing n8n’s port publicly.
Create a private .env file beside the Compose file. Add unique database credentials, the domain, timezone, and a long random encryption key. Set file permissions so only the deployment owner can read it, and exclude it from version control. The encryption key protects stored credentials; losing it can make those credentials unusable after restoration. The n8n self hosting setup depends on preserving this key securely alongside backups, but separately from public project files.
Read the official n8n Docker installation documentation for current environment variables and image details. Avoid copying old examples blindly: variable names and supported options can change across releases. Before launch, review the Compose file, verify that no secret is committed, and confirm that only the intended services and ports are exposed.
3. Launch and Verify the Local n8n Server
Once the files are ready, validate the configuration before creating containers. From the project directory, run docker compose config. This checks the Compose structure and resolves environment substitutions; treat the rendered output as sensitive because it may include secrets. Correct missing variables or YAML indentation problems before you continue. This small check catches many avoidable startup failures.
Start the stack with docker compose up -d, then inspect docker compose ps to see whether both services are running. If n8n exits or repeatedly restarts, review docker compose logs --tail=100 n8n and the corresponding PostgreSQL logs. Common causes include a wrong database password, a database that has not become healthy, an unsupported configuration value, or a port already in use. The local n8n server should be tested before you route real business traffic to it.
Open the n8n editor through the intended secure route and complete the initial account setup. Use a unique administrator password and enable any available account protections appropriate to your deployment. Confirm that the displayed public URL and generated webhook URLs use HTTPS and the correct hostname. If n8n reports an internal address or generates HTTP links, inspect the reverse proxy headers and the configured host, protocol, and webhook URL.
Test persistence, not just availability. Create a disposable workflow, save it, restart n8n with docker compose restart n8n, and confirm it remains. Restarting a container should not erase workflows or credentials because data lives in named volumes and PostgreSQL. Do not test persistence by deleting volumes: commands such as docker compose down -v remove them and can permanently erase application data.
Next, run a small workflow that exercises the same network path as a real use case. For a scheduled workflow, check that its timezone and next-run time are correct. For a webhook, send a test request through the public HTTPS hostname and verify that the execution appears in n8n. For an API integration, use a low-risk test account and confirm that credentials are stored and usable. Guidance on connecting an API with n8n’s HTTP Request node can help troubleshoot request configuration.
Some integrations call back into n8n, while others only require outbound connections. Confirm the relevant direction of traffic rather than opening broad firewall access “just in case.” If a local n8n server is intended only for internal use, verify from an external network that the editor and port 5678 are not reachable. If it must receive public webhooks, expose only the reverse proxy on standard web ports, enforce HTTPS, and keep the editor protected.
Write down the checks that passed, the image version deployed, and any non-default settings. Include a quick way to stop and start the services, and identify the person responsible for alerts. With this verification complete, your n8n self hosting setup is ready for carefully staged workflows—not yet for an untested migration of every production automation.
4. Secure Access, Secrets, and Workflow Behavior
Security starts with reducing exposure. Configure the host firewall to allow only required traffic, typically SSH from trusted sources and HTTPS to the reverse proxy. Use key-based SSH authentication where possible, disable password-based remote access when your operations policy permits, and keep the operating system patched. Do not publish PostgreSQL’s port or leave the n8n editor open to the internet without a deliberate access policy.
Use a reverse proxy such as Nginx, Caddy, or Traefik to terminate TLS and forward requests to n8n. Keep proxy certificates renewed and configure forwarded headers as recommended by n8n and your proxy. Set the correct public host, protocol, and webhook URL in n8n’s environment. A mismatch can produce callback failures, insecure links, or redirect loops. Before changing proxy rules, test them with a temporary workflow and confirm both editor access and webhook delivery.
Protect secrets at several layers. Use a unique, high-entropy encryption key and database password; restrict the .env file; and limit shell access to trusted operators. Do not put API keys in workflow notes, sample payloads, or exported JSON files. Treat workflow exports and execution data as sensitive because they may contain internal URLs or personal information, even when credentials are encrypted separately.
Set execution data retention deliberately. Detailed inputs and outputs can help troubleshoot a failure, but they also increase storage requirements and the amount of data retained. Review n8n’s execution-data settings and choose a retention period appropriate to operational needs and applicable policies. Test that pruning behaves as expected, and check database growth after workflows begin running. Keep only the information needed for useful monitoring and recovery.
Good workflows also fail safely. Add error paths for critical automations, send alerts to a monitored channel, and make actions idempotent where repeated execution could create duplicate records or payments. Start with a low-risk subset of the business process, then expand after logs and alerts show expected behavior. For branching cases, see these n8n conditional logic patterns; for resilience, review practical n8n error-handling approaches.
Review who can create, edit, and activate workflows. A workflow can use the permissions of connected services, so access to the editor may effectively grant access to sensitive systems. Separate development and production credentials when feasible, and remove credentials that are no longer needed. For workflows calling external APIs, follow a least-privilege approach and rotate tokens according to the provider’s policy. The n8n self hosting setup gives you control over these decisions, but control only helps when someone actively applies it.
Finally, document an incident response path. Include how to disable a misbehaving workflow, revoke an exposed integration token, inspect logs, and restore a known-good backup. Avoid putting credentials in alerts or shared incident notes. A brief, rehearsed response can prevent a minor configuration error from becoming a prolonged outage or data exposure.
5. Back Up, Update, and Control Operating Costs
A production-ready deployment needs recoverable backups, not merely persistent volumes. Back up the PostgreSQL database and the n8n configuration volume, and preserve the exact encryption key required to decrypt saved credentials. Store copies away from the host—for example, in a secured object-storage bucket or a separate backup system—with access controls and encryption appropriate to the data. A backup kept only on the server does not protect against disk failure, host compromise, or accidental deletion.
For PostgreSQL, a logical dump can be created with a command such as docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > n8n-db.sql, run in a shell where the needed variables are safely available. Protect the resulting file because workflow records can contain sensitive data. Back up the n8n data volume using a method suitable for your storage and consistency requirements. For an especially important system, briefly stop writes or use a coordinated snapshot process so database and file backups represent a compatible point in time.
Schedule backups and define how long to retain them. Then perform a restoration test on an isolated host or temporary environment. Confirm that workflows appear, credentials can be decrypted, and a harmless test execution completes. Record the time required to restore; that result tells you whether your recovery plan meets business expectations. A backup that has never been restored is an assumption, not a proven recovery method.
Update with a repeatable process. Read the release notes, check compatibility and migration guidance, and take a fresh backup before changing the image version. Test the update in a staging environment when possible. Change the pinned image tag in Compose, pull the image with docker compose pull, then apply it with docker compose up -d. Review logs, sign in, run a sample workflow, and verify webhooks. Keep a rollback plan, while recognizing that database migrations may affect how simple a rollback can be.
Monitor the host’s disk, memory, CPU, container health, and database size. Alerts for a full disk or a stopped service are more useful than discovering the problem through a missed customer process. Track workflow failures and execution volume as well. If demand grows, assess whether retention, workflow design, or available host resources are the bottleneck before adding complexity. Queue mode and worker services can support larger workloads, but they introduce additional components and operational requirements.
Control costs by reviewing the whole operating picture: compute, storage, backups, monitoring, network needs, and staff time. Docker Compose and open-source software can reduce recurring platform charges, but they do not eliminate infrastructure or maintenance costs. Choose resource levels based on observed usage, keep execution retention proportionate, and avoid paying for idle capacity without a clear availability reason. Compare those expenses periodically with the value of data control and the cost of operating alternatives.
Maintain a simple deployment record with the Compose file version, image tags, environment variable names, backup location, last restore-test date, and update owner. Never record secret values in it. This makes the n8n self hosting setup easier to hand off and reduces dependence on one administrator’s memory. If your organization later moves the service, the same documentation also clarifies which data and security controls must travel with it.
For further reading, see Google Search Central.
For further reading, see the MDN Web Docs.
Frequently Asked Questions
Is a self-hosted n8n deployment free?
The software can be used without paying a hosted-service subscription, but running it is not cost-free. You may pay for a server, storage, backups, monitoring, and network services, and someone must maintain and secure the host. Compare the total operating effort and infrastructure costs with hosted alternatives before choosing.
Can I run n8n on my laptop?
Yes, a local n8n server on a laptop is useful for learning, testing credentials, and prototyping workflows. It may stop when the computer sleeps, disconnects, or changes networks, so it is usually unsuitable for business processes that need dependable scheduled runs or public webhooks. Move stable workflows to an always-on host when required.
Do I need PostgreSQL for this n8n self hosting setup?
Not for every experiment, but PostgreSQL is a sensible database choice for a maintained deployment. It separates application data from the container lifecycle and is designed for persistent database workloads. Whatever database you choose, configure backups, preserve the encryption key, and test restoration rather than relying on container state alone.
How do public webhooks reach a private Docker deployment?
Use a public DNS name and an HTTPS reverse proxy that forwards requests to n8n. Set n8n’s public host and webhook URL to match that address, and allow inbound traffic only on the required web ports. A VPN-only deployment cannot receive webhooks from external services unless the relevant network path is made available.
What should I back up before an update?
Back up the PostgreSQL data, the n8n data volume, and the encryption key, then confirm the backup is stored away from the host. Record the current image version and read release notes before updating. For a critical service, test restoration and the proposed update in an isolated environment first.
Conclusion: Deploy with Control and a Recovery Plan
A dependable n8n self hosting setup is more than a Compose file. It combines persistent data, correctly configured public URLs, restricted network access, protected secrets, verified backups, and a routine for updates. Docker Compose makes the services easier to describe and reproduce, while the operating practices around it determine whether the system remains secure and recoverable.
Start with a small deployment, validate one low-risk workflow, and test a restore before moving critical automations. Then review infrastructure and maintenance costs against the data control and flexibility you gain. If you want help designing an automation environment that fits your processes, talk with Seelaunch LLC about your automation goals.



