If you run n8n with Docker Desktop for more than a quick test, the editor is only part of the setup. The settings that decide whether your instance survives a restart live outside the canvas: timezone, encryption key, port mapping, host names, and persistent storage.
This is where a lot of beginner n8n installs get quietly fragile. The workflow works once, the container gets recreated later, and suddenly the thing you thought you saved is missing or the credential cannot be decrypted.
The fix is not a complicated production stack. For a local learning setup, you just need a small Compose folder that keeps ordinary configuration readable, keeps real secrets out of Git, and gives you a simple restart check before you trust the setup.
This article is for people running n8n on Docker Desktop for Mac or Windows, including people connecting n8n to Ollama. If you have not installed Docker Desktop or n8n yet, start with the basic n8n Docker installation guide first. This walkthrough assumes you can open a terminal and run Docker Compose. It is not a production deployment guide.
Where n8n environment variables go
There are three places to keep straight: the private .env file, the public-ish compose.yaml file, and the n8n container itself.
The .env file stores values Docker Compose can substitute. The compose.yaml file decides which of those values are actually passed into the n8n container. Then n8n reads supported variables such as N8N_ENCRYPTION_KEY and GENERIC_TIMEZONE.
A value in .env is not automatically useful to n8n. It must also be referenced under the service’s environment: section in compose.yaml. The official n8n environment variables reference is the place to check exact variable names before you rely on them.
For example:
environment:
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
Docker also documents the different ways to set environment variables in Compose. For this beginner setup, the explicit .env plus environment: pattern is the easiest one to inspect.
In plain English: putting a value in .env gives Compose something to read. Referencing it under environment: is what hands it to n8n.
Ordinary configuration versus secrets
Not every environment variable is a secret.
Values like N8N_HOST, N8N_PORT, N8N_PROTOCOL, GENERIC_TIMEZONE, and TZ are ordinary configuration. They still matter, but they are not the same kind of risk as a credential.
The n8n encryption key is sensitive. Treat it as a secret even though it is written as an environment variable in this beginner setup. Anyone who obtains it may be able to affect how n8n protects stored credentials.
Docker Compose environment variables are convenient, but they are not automatically secure. Do not commit a real .env file to GitHub, paste real keys into screenshots, or send the file in a support forum.
For a production or shared environment, use a more deliberate secrets-management approach. Docker documents Compose secrets for sensitive values where that model fits. This local tutorial keeps the setup understandable and is not a replacement for production secrets management.
Create the three files
Make a new folder for this setup:
n8n-local/
├── compose.yaml
├── .env.example
└── n8n-config-checklist.md
Copy the following contents into the files.
File 1: compose.yaml
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
ports:
- "${N8N_PORT}:5678"
environment:
N8N_HOST: ${N8N_HOST}
N8N_PORT: 5678
N8N_PROTOCOL: ${N8N_PROTOCOL}
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
TZ: ${TZ}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
# Optional convenience value for local Ollama experiments.
OLLAMA_HOST: ${OLLAMA_HOST}
volumes:
- n8n_data:/home/node/.n8n
restart: unless-stopped
volumes:
n8n_data:
This file publishes n8n on the port in your .env file, passes the important n8n settings into the container, includes an optional Ollama host value for local experiments, and stores n8n data in the named n8n_data volume.
The persistent volume is mounted at /home/node/.n8n, which is where the n8n container stores important local data. Without a persistent volume, recreating the container can make your local setup appear to lose its data.
The latest image tag is convenient for learning, but it can change over time. For a more controlled setup, replace it with a specific n8n version after checking the current n8n documentation.
File 2: .env.example
# Local n8n address
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=http
# Use your local timezone, for example America/Chicago.
# Replace this with a valid IANA timezone for your location.
GENERIC_TIMEZONE=America/Chicago
TZ=America/Chicago
# Replace this with a long, private value before starting n8n.
# Do not commit the real value to Git.
N8N_ENCRYPTION_KEY=replace-with-a-long-private-encryption-key
# Optional Ollama value for local Docker Desktop experiments.
# Docker Desktop commonly uses host.docker.internal to reach a service
# running on the host machine. This is not universal across all setups.
OLLAMA_HOST=http://host.docker.internal:11434
Copy the example file to a real .env file:
cp .env.example .env
On Windows PowerShell, use:
Copy-Item .env.example .env
Now edit .env and replace the encryption-key placeholder with a long private value.
For example, the final line might look like this:
N8N_ENCRYPTION_KEY=use-your-own-long-random-private-value
That value is illustrative. Do not copy it as your real key.
Keep the same encryption key when restarting or recreating the container. Changing it later can prevent n8n from decrypting credentials that were saved with the original key.
Add .env to your Git ignore file if this folder is a Git repository:
.env
The .env.example file is safe to share because it contains placeholders. The real .env file is not.
File 3: n8n-config-checklist.md
# n8n local configuration checklist
## Before the first start
- [ ] Copy `.env.example` to `.env`.
- [ ] Replace `N8N_ENCRYPTION_KEY` with a private value.
- [ ] Confirm `.env` is ignored by Git.
- [ ] Set `GENERIC_TIMEZONE` and `TZ` to the intended IANA timezone.
- [ ] Confirm `N8N_PORT` is available.
- [ ] If using Ollama, confirm Ollama is running on the host.
- [ ] Do not assume `localhost` inside the n8n container means the host.
## Start
```bash
docker compose up -d
```
Open `http://localhost:5678`.
## Before restart
- [ ] Confirm the editor opens.
- [ ] Confirm a test workflow exists.
- [ ] Confirm any test credential is present.
- [ ] Confirm the `n8n_data` volume exists.
## Restart and verify
```bash
docker compose restart
docker compose ps
docker compose logs --tail=100 n8n
```
- [ ] The container is running.
- [ ] The editor opens.
- [ ] The test workflow still exists.
- [ ] The test credential is still available.
- [ ] Any timezone-dependent test behaves as expected.
- [ ] An Ollama test works, if configured.
Keep this checklist beside the Compose files. It is a local learning aid, not a substitute for backups or production operations.
Start the setup
From the folder containing compose.yaml, run:
docker compose up -d
Then open:
http://localhost:5678
The first startup may take a little time while Docker downloads the image.
To see whether the container is running:
docker compose ps
To view recent n8n logs:
docker compose logs --tail=100 n8n
The log command is useful for diagnosis. It does not replace checking the editor in your browser.
Connecting n8n to Ollama
A common beginner setup runs Ollama directly on the Mac or Windows host and n8n inside Docker.
That creates an annoying little networking distinction. From inside the n8n container, localhost usually points back to the n8n container, not automatically to the computer running Docker Desktop. In many Docker Desktop setups, host.docker.internal is the route from the container back to a service on the host.
That is why the example uses:
OLLAMA_HOST=http://host.docker.internal:11434
This value is an illustrative Docker Desktop setting, not a universal rule for every operating system, network mode, or Ollama installation.
The n8n Ollama credential still needs to use the matching base URL. Ollama has its own n8n integration guidance, and your Compose variable is only a local convenience unless your workflow or credential actually uses it. Putting OLLAMA_HOST in the Compose environment does not necessarily configure the credential automatically.
If your Ollama process is running in another container, on another computer, or with a custom port, use the address that matches that arrangement instead.
Avoid changing several things at once. First confirm that n8n opens. Then confirm Ollama is reachable from the host. Then configure the n8n credential and run a small test.
What _FILE variables mean
Some n8n settings have a corresponding _FILE form. For example, a setting may support:
environment:
N8N_ENCRYPTION_KEY_FILE: /run/secrets/n8n_encryption_key
The idea is that the application reads the value from a mounted file instead of receiving the secret directly as an ordinary environment variable.
The catch is that _FILE support is selective. You cannot add _FILE to every variable name and expect n8n to understand it. It also only helps if the secret file is actually mounted into the container through a suitable file or secrets mechanism.
Do not add _FILE to arbitrary variable names and expect it to work. Check the n8n documentation for the specific setting and the n8n version you are using.
For this beginner Compose example, the encryption key is shown as an ordinary environment variable so the complete setup is easy to understand. That is acceptable for a private learning computer only if you protect the .env file. It is not a claim that the value is automatically secure.
Verify persistence with a restart
A restart test should confirm more than whether the container comes back up. It should show that n8n can still read its stored data and credentials.
The following is an ILLUSTRATIVE / NOT_RUN verification scenario.
Start the stack with docker compose up -d, open http://localhost:5678, and create one harmless test workflow. If your workflow needs a credential, use a test credential. Then run docker compose ps, restart with docker compose restart, and check docker compose ps again.
After the restart, reopen the editor. The useful check is whether the editor loads, the test workflow still exists, the test credential is still available, timezone behavior looks right, and an Ollama test works if you configured Ollama. If something fails, inspect recent logs with docker compose logs --tail=100 n8n.
A successful restart is evidence that the container can come back with the same configuration and persistent data. It is not a complete backup test. You should still learn how your Docker volume is backed up before storing anything important.
Common beginner mistakes
Putting variables only in .env
Docker Compose can read .env for substitution, but n8n only receives values that you reference under environment: in compose.yaml.
Committing .env
The .env file can contain your encryption key and other private values. Keep .env.example in version control, not .env.
Changing the encryption key during troubleshooting
Keep the original key while troubleshooting an existing n8n data directory. Changing it can make previously stored credentials unreadable.
Removing the volume
Removing the n8n_data volume removes the persistent data associated with this setup. Do not run volume-removal commands casually.
Using localhost for host-side Ollama
Inside the n8n container, localhost normally points back to that container. Docker Desktop commonly provides host.docker.internal for reaching a service on the host, but the correct address depends on how your services are running.
Assuming local means completely isolated
n8n may run locally while Ollama, model downloads, integrations, or external APIs still communicate over a network. Treat credentials and workflow data accordingly.
Treating this as production infrastructure
This example is for local learning. It does not cover TLS, reverse proxies, access control, backups, monitoring, upgrades, or a full secrets-management design.
FAQ
Do I need both GENERIC_TIMEZONE and TZ?
For this beginner setup, keeping both values aligned makes the intended timezone clear to n8n and the container environment. Use the same valid IANA timezone in both places.
Can I use a different n8n port?
Yes. Change the host-side value in .env:
N8N_PORT=5679
The Compose mapping will then expose n8n at:
http://localhost:5679
The container still listens on port 5678 in this example.
Why is N8N_PORT set to 5678 in compose.yaml?
The example separates the host port from the container port. N8N_PORT in .env controls the port on your computer, while the n8n process inside the container listens on its internal port.
Can I put the encryption key directly in compose.yaml?
You can, but it makes accidental sharing easier. Keeping it in .env is clearer for a local setup, provided you protect .env and exclude it from Git.
Is the named volume enough for backups?
No. A named volume provides persistence across normal container restarts and recreation, but it is not automatically a backup. Learn how to back up the volume before relying on it for important workflows or credentials.
Does OLLAMA_HOST configure the n8n Ollama node?
Not necessarily. In this example, it is an optional convenience value passed into the container. Configure the n8n Ollama credential with the correct base URL as well.
Should I use latest for a long-running setup?
latest is convenient for learning but can change over time. Version drift can change supported variables, defaults, or behavior. For repeatable deployments, pin and test a specific n8n version.
Final takeaway
For a beginner n8n Compose setup, keep editable values in a private .env file, reference those values explicitly in compose.yaml, and store n8n data in a persistent volume. Treat the encryption key as sensitive, keep the real .env out of Git, and verify host connections such as host.docker.internal in your own Docker Desktop setup.
The first useful check is simple: start n8n, create a test workflow, restart the container, and confirm that the workflow is still there.
For the broader automation pattern, explore AI Workflows and the Free n8n Workflow Library.
Free GetPrompting Starter System
Turn what you learned into something useful.
Get the Starter System, practical workflow notes, and a short path for choosing what to explore next.