Not tested202,971

Automation

n8n

n8n connects services to each other without programming: a workflow is built from nodes on a canvas, runs on a schedule, a webhook, or an event, and can branch, retry steps, and handle errors. Over five hundred ready-made integrations, a node for custom JavaScript and Python, and LLM support. Your data and credentials stay on your own server.

Overview

n8n is a workflow automation builder: a workflow is assembled on a canvas from nodes, where each node receives data from the previous one, transforms it, and passes it on. Runs are triggered by a schedule, a webhook, an event in an external service, or manually from the editor. There are branches, loops, retries, and separate error-handling paths.

More than five hundred ready-made integrations ship with it — email, messengers, databases, CRMs, cloud storage, LLM providers. Anything missing is covered by a generic HTTP request node or a node with your own JavaScript and Python code. Unlike Zapier and Make, both the workflows and the credentials for those services stay on your own server.

The recipe runs n8n together with PostgreSQL: on SQLite the execution history quickly runs into write locks. The panel is published on 127.0.0.1:5678 only.

No isolated smoke test has been run yet, so this published recipe remains unverified.

Security assessment

The containers run without privileged, host networking, or the Docker socket, and with no-new-privileges. PostgreSQL is not published to the host at all, and the n8n port is bound to 127.0.0.1.

What makes n8n special is that the instance accumulates access to every service you connect. Those credentials sit encrypted in the database, and the key comes from N8N_ENCRYPTION_KEY. A database dump together with .env is equivalent to the keyring for your mail, CRM, and cloud storage at once, so the archives must be stored and transferred as secrets.

The second risk is code execution. The Code node runs arbitrary JavaScript and Python, and community nodes install npm packages into the instance. All of it runs with the privileges of the n8n process inside its container. The official sandboxed runner isolates such code but requires privileged Docker-in-Docker, so it is not part of this recipe: grant editor access only to people you trust to run code on the server.

Third, webhooks and the editor live on the same port. Publishing a webhook to the internet also exposes the control panel, so HTTPS and a strong owner password are mandatory.

Update tracking

These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.

New releases

Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.

Current version 2.36.9Aug 31, 2026, 11:16 PM UTC

Critical vulnerabilities

Result of a dedicated Docker image scan, not a Compose configuration check.

Not checkedNot checked

Breaking updates

A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.

Not checkedNot checked

compose.yaml

Upstream Compose changes relative to the verified recipe.

Upstream Compose is not trackedNot checked

Outdated Docker images

Pinned image tags checked for newer versions.

All images are currentAug 31, 2026, 11:16 PM UTC

From observation to action

Update plan

The recipe already pins the latest known release. The steps below show the evidence retained for that version.

2.36.92.36.9
  1. Open the release evidence

    There is no exact release-notes URL for this manually tracked source. Start with the project sources below.

  2. Review the version boundary

    The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.

  3. Prepare image-tag changes

    No image-tag change is currently planned.

  4. Follow the documented migration shape

    Migration, majors cannot be skipped. Release-specific migration steps still come from the release notes and installation guide.

  5. Protect the rollback point

    No version change is currently planned. The recipe includes a backup procedure. Restore has not been tested.

  6. Verify the updated recipe

    No check-history entry exactly matches application version 2.36.9; do not present the update as verified.

Read the update procedure in the installation guide ↓

Specifications

Security and exposure

Installation levels

The status shows how fully the published recipe meets each level's requirements.

Ready

For home

A minimal setup for a local network or access through a VPN.

  • Single server
  • Local access
  • Minimum components

The recipe covers every requirement at this level.

Ready

For a VPS

A public deployment with protected access and backups.

  • Domain
  • HTTPS via reverse proxy
  • Off-server backup

The recipe covers every requirement at this level.

Partial

Reliable

A setup designed for predictable operations and observability.

  • Separate database
  • Healthcheck
  • External monitoring
  • CPU and memory limits

You still need to add: external monitoring, cpu and memory limits.

Tailored to your server

Configuration generator

Answer five questions and download a ready-to-run n8n bundle.

Runs locally
01 Do you have a domain?
02 Which reverse proxy?
03 Server architecture
04 Where should data be stored?

Use an absolute path for a separate disk, such as /srv/n8n.

05 Is VPN access required?

Your bundle is ready

The archive is created in your browser. Your answers are never sent anywhere.

Screenshots

Screenshots have not been added yet.

Quick start

Read the full guide first: it explains external access, backups, and data locations.

Prepare settingscp .env.example .env
Launchdocker compose up -d
Check statusdocker compose ps

Step-by-step guide

1. Check the Ubuntu or Debian server

Minimum: 2 CPU, 1 GB RAM, and 5 GB of disk. 2 GB RAM is recommended — usage grows with the number of concurrent executions and the size of their history. You need Ubuntu 22.04+ or Debian 12+ with Docker Engine and Docker Compose v2.24+. PostgreSQL comes up from the same Compose file; no separate install.

docker --version
docker compose version

2. Prepare the files and variables

Put compose.yaml, .env.example, backup.sh, restore.sh, and the proxy directory into a dedicated directory:

mkdir -p ~/services/n8n
cd ~/services/n8n
cp .env.example .env
chmod 600 .env

Fill in the two mandatory secrets — do not start without them:

sed -i "s|^N8N_ENCRYPTION_KEY=.*|N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)|" .env
sed -i "s|^N8N_DB_PASSWORD=.*|N8N_DB_PASSWORD=$(openssl rand -hex 24)|" .env

N8N_ENCRYPTION_KEY encrypts the passwords and tokens of every connected service. Never change it after the first start: with the existing database, a new key makes the stored credentials unreadable. Keep the key in a password manager, separately from the server.

The remaining .env variables:

  • N8N_VERSION — the pinned image tag; the stable line is 2.36.x, while 2.37.x tags on Docker Hub belong to the beta channel;
  • N8N_PORT — the local editor port, 5678 by default;
  • N8N_DB_NAME and N8N_DB_USER — database name and user, changeable only before the first start;
  • N8N_PUBLIC_HOST and N8N_PROTOCOL — external host name and scheme, used in the links the UI generates;
  • N8N_WEBHOOK_URL — the full external address when publishing behind a reverse proxy;
  • N8N_SECURE_COOKIE — whether the session cookie is sent over HTTPS and localhost only;
  • N8N_PROXY_HOPS — the number of reverse proxies in front of n8n;
  • N8N_DIAGNOSTICS and N8N_VERSION_NOTIFICATIONS — telemetry and update checks, disabled by default;
  • N8N_EXECUTIONS_MAX_AGE_HOURS — how long the execution history is kept, two weeks by default;
  • N8N_DATA_VOLUME and N8N_DB_VOLUME — the Docker volume names;
  • TZ — the time zone, which the Schedule and Cron nodes follow.

Data lives in two volumes: n8n-data holds the encryption key, settings, and binary execution data, while n8n-database holds the workflows, credentials, and history. Nothing is stored in the recipe directory.

3. Start it on a VPS

docker compose pull
docker compose up -d
docker compose ps

The first start takes longer than usual: n8n runs the database migrations. The default port is reachable on 127.0.0.1 only, and PostgreSQL is not published to the host at all.

4. Create the instance owner

ssh -L 5678:127.0.0.1:5678 user@server.example

Open http://localhost:5678, create the owner account, and store the password in a password manager. Until the owner exists the UI is reachable without authentication, so do not expose the port before this step.

Local network

Without a reverse proxy it is safer to keep the localhost bind and use an SSH tunnel. If the editor has to be reachable from a trusted LAN, replace 127.0.0.1 in compose.yaml with the server address, for example 192.168.1.10, and do not use 0.0.0.0.

Over plain HTTP on a non-localhost address n8n will not send the session cookie, and the login silently fails. For that case, in .env:

sed -i 's/^N8N_SECURE_COOKIE=.*/N8N_SECURE_COOKIE=false/' .env
sed -i 's|^N8N_PUBLIC_HOST=.*|N8N_PUBLIC_HOST=192.168.1.10|' .env
docker compose up -d

Turning N8N_SECURE_COOKIE off means the session cookie travels in clear text. That is acceptable inside a trusted network only; for outside access set up HTTPS.

Domain and HTTPS

The samples live in proxy/Caddyfile, proxy/nginx.conf, and proxy/traefik.yaml; replace n8n.example.com with your domain. Caddy obtains a certificate automatically, the Nginx sample assumes a Certbot certificate, and Traefik uses the letsencrypt resolver. For Traefik in a container, replace 127.0.0.1 with a host gateway address the container can reach.

After publishing, set the external address — otherwise webhooks hand out localhost links that external services cannot reach:

sed -i 's|^N8N_WEBHOOK_URL=.*|N8N_WEBHOOK_URL=https://n8n.example.com/|' .env
sed -i 's|^N8N_PUBLIC_HOST=.*|N8N_PUBLIC_HOST=n8n.example.com|' .env
sed -i 's|^N8N_PROTOCOL=.*|N8N_PROTOCOL=https|' .env
sed -i 's|^N8N_PROXY_HOPS=.*|N8N_PROXY_HOPS=1|' .env
docker compose up -d

Publishing webhooks also exposes the editor: it lives on the same port. Restrict access by IP or with basic authentication on the proxy side if only the webhooks need to be reachable.

Backup

The script stops n8n, takes a PostgreSQL dump, and archives the volume holding the encryption key — separately they are useless:

chmod +x backup.sh restore.sh
./backup.sh

The archive appears in ./backups. It contains decryptable access to every connected service, so keep a copy off the server and encrypt it.

Restore

Restoring completely replaces the database and the data directory with the chosen archive:

./restore.sh ./backups/n8n-YYYYMMDDTHHMMSSZ.tar
docker compose ps

Before the replacement the script creates a safety copy of the current state. The N8N_ENCRYPTION_KEY value in .env must match the one the archive was made with, otherwise the workflows come back but the service credentials do not.

Update

Create a backup, read the release notes, change N8N_VERSION in .env, then run:

./backup.sh
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 n8n

Do not skip major versions: the migrations expect sequential upgrades. Stay within the stable 2.36.x line while 2.37.x remains the beta channel.

Rollback

Restore the previous N8N_VERSION in .env and run docker compose pull and docker compose up -d. If the new version already ran its database migrations, rolling the image back is not enough: the older n8n cannot read the new schema. In that case restore the archive made before the update:

./restore.sh ./backups/n8n-YYYYMMDDTHHMMSSZ.tar

This is why a backup before every update is mandatory: it is the only thing that makes a rollback possible.

Removal

Keep the data: docker compose down. Remove the containers and all data irreversibly:

docker compose down
docker volume rm n8n-data n8n-database
rm -rf ~/services/n8n

Disable the webhooks in the external services before removal, or they will keep hitting an address that no longer exists.

Sources: Docker installation, environment variables, and updating.

Troubleshooting

Login does not go through: the form accepts the password and returns to the login screen

n8n does not send the session cookie over plain HTTP unless the address is localhost. Check how you open the UI. Through an SSH tunnel on localhost everything works with the defaults. For access by IP inside a trusted network, set N8N_SECURE_COOKIE=false in .env and recreate the container:

docker compose up -d

The proper fix for outside access is HTTPS behind a reverse proxy, not a disabled flag.

The n8n container never becomes healthy

docker compose ps
docker compose logs --tail=200 n8n

The first start takes longer: the database migrations are running. If the logs show ECONNREFUSED against database, check the state of PostgreSQL — n8n only starts after its healthcheck passes:

docker compose logs --tail=100 database

Credentials stopped opening after a migration

This is almost always a mismatched N8N_ENCRYPTION_KEY. Workflows and history travel in the database dump, but service passwords are encrypted with the key, which lives in .env and in config inside the n8n-data volume. Verify that the key is the same:

grep N8N_ENCRYPTION_KEY .env
docker compose exec n8n cat /home/node/.n8n/config

If the old key is lost, the credentials cannot be recovered and have to be entered again.

An external service’s webhook never arrives

Open the Webhook node and look at the Production URL. If it says localhost, N8N_WEBHOOK_URL is not set:

grep -E 'N8N_WEBHOOK_URL|N8N_PUBLIC_HOST|N8N_PROTOCOL' .env

Fill them in with the external address and run docker compose up -d. Remember that a node’s test URL only lives while the editor is open, and the production one appears after the workflow is activated.

The database grows and the disk fills up

The execution history is pruned according to N8N_EXECUTIONS_MAX_AGE_HOURS. Check the size:

docker compose exec -T database psql -U n8n -d n8n \
  -c "select pg_size_pretty(pg_database_size('n8n'))"

Lower the retention in .env and recreate the container. Also check individual workflows: each one can stop saving successful executions.

A workflow does not run on schedule

The Schedule and Cron nodes follow GENERIC_TIMEZONE, which comes from TZ in .env. Check the zone inside the container:

docker compose exec n8n date

And make sure the workflow is activated with the toggle in the editor: a saved but inactive workflow never runs on schedule.

The Code node fails with a file or network access error

In this recipe the code runs inside the n8n container, without the external sandboxed runner. Some operations are limited by the file system access settings. Do not weaken those limits on an instance whose editor several people can reach: the Code node runs arbitrary code with n8n’s privileges.

Official sources

Latest release: 2026-08-31 · GitHub Stars: 202,971 · metadata checked Aug 31, 2026, 9:46 PM UTC

Disclaimer

Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.

A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.