New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
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.
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.
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.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
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.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
2.36.92.36.9There is no exact release-notes URL for this manually tracked source. Start with the project sources below.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Migration, majors cannot be skipped. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has not been tested.
No check-history entry exactly matches application version 2.36.9; do not present the update as verified.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
The recipe covers every requirement at this level.
A public deployment with protected access and backups.
The recipe covers every requirement at this level.
A setup designed for predictable operations and observability.
You still need to add: external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run n8n bundle.
Screenshots have not been added yet.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psMinimum: 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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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 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.
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.
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.
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.