Self-Hosting n8n in the EU: A GDPR-Conscious Setup Guide
To self-host n8n in the EU, run it with Docker Compose on a server in an EU data centre, put a TLS reverse proxy in front, persist the n8n data volume, set your own encryption key, switch off telemetry and external update checks, and prune execution data.
This guide is for teams that want n8n workflows running on infrastructure they control in Europe. It covers n8n itself. It does not make the services your workflows call any more European, which is why the last step is a data-flow check.
Prerequisites
- A Linux server in an EU data centre with Docker Engine and Docker Compose installed.
- A domain or subdomain whose DNS A record points to the server.
- A password manager for the encryption key and server credentials.
1. Follow the official Docker Compose layout
n8n recommends a project directory with a .env file, a compose.yaml and a local-files folder shared with the container. Its documented setup runs Traefik as a second container to handle TLS certificates and routing, and publishes the n8n port only on 127.0.0.1 so traffic must go through the proxy.
The documented .env variables are DOMAIN_NAME, SUBDOMAIN, GENERIC_TIMEZONE and SSL_EMAIL. Use the official compose file as your base and add the privacy settings below.
2. Add the privacy and retention settings
This trimmed example shows the n8n service only. Pin an exact image version instead of a floating tag, and check the official compose file for the current image name and variable names. From n8n 2.30.0 the documentation uses N8N_WEBHOOK_URL; earlier versions use WEBHOOK_URL.
services:
n8n:
image: docker.n8n.io/n8nio/n8n:<pinned-version>
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.example.com/
- GENERIC_TIMEZONE=Europe/Brussels
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_DIAGNOSTICS_ENABLED=false
- N8N_VERSION_NOTIFICATIONS_ENABLED=false
- N8N_TEMPLATES_ENABLED=false
- N8N_PERSONALIZATION_ENABLED=false
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:| Setting | Default | What it does |
|---|---|---|
| N8N_DIAGNOSTICS_ENABLED | true | Shares anonymous telemetry with n8n. Setting it to false also disables Ask AI in the Code node. |
| N8N_VERSION_NOTIFICATIONS_ENABLED | true | Queries n8n for new versions and security updates. Turning it off means you must watch releases yourself. |
| N8N_TEMPLATES_ENABLED | true | Enables the workflow template library. |
| N8N_PERSONALIZATION_ENABLED | true | Asks users personalization questions. |
| EXECUTIONS_DATA_PRUNE | true | Deletes old execution data on a rolling basis. |
| EXECUTIONS_DATA_MAX_AGE | 336 (hours) | Maximum age of an execution before deletion. |
3. Set and protect the encryption key
n8n uses N8N_ENCRYPTION_KEY to encrypt credentials before saving them to the database. If you do not set one, n8n generates a random key on first launch and stores it in the ~/.n8n folder, which is the n8n_data volume in this setup. Set the key yourself, store it in your password manager, and in queue mode set it on every worker.
n8n documents what the key does but not how to recover from losing it. Treat it like a root password and back it up.
4. Decide what execution data you keep
By default n8n saves execution data for both successful and failed runs, prunes it after 336 hours and keeps at most 10,000 executions. Execution data can contain the personal data your workflows process. For sensitive workflows, shorten EXECUTIONS_DATA_MAX_AGE and consider setting EXECUTIONS_DATA_SAVE_ON_SUCCESS to none.
5. Back up the data volume
The n8n_data volume holds n8n's SQLite database and the encryption key. Back it up to a second EU location and test a restore. If you move to PostgreSQL, back up the database as well.
6. Map where data really goes
Self-hosting keeps n8n's own data on your server. Every node that calls an outside service sends data to that service, wherever it is hosted. List each workflow, the services it calls and the personal data it passes, then check the provider's location and contract.
| Data flow | Where it goes | What you control |
|---|---|---|
| n8n telemetry | n8n servers | Switch off with N8N_DIAGNOSTICS_ENABLED=false |
| Version checks | n8n servers | Switch off with N8N_VERSION_NOTIFICATIONS_ENABLED=false |
| Template library | n8n servers | Switch off with N8N_TEMPLATES_ENABLED=false |
| Workflow nodes (AI, CRM, email, storage) | Each provider you connect | Provider choice, region and contract |
Your hosting provider and any API provider act on your behalf when they process personal data. Ask your data protection officer which processor agreements you need.
Common mistakes
- Using a floating image tag so an update changes behavior unannounced.
- Leaving the encryption key only inside the container volume.
- Keeping execution history forever.
- Assuming an EU server makes every connected API an EU service.
Frequently asked questions
Does self-hosting n8n make my automations GDPR-conscious?
It gives you control over where n8n stores its own data, which helps. It does not cover what your workflows send to third-party services, so you still need a data-flow review and the right agreements.
Where does n8n store credentials?
In its database, encrypted with the encryption key before they are saved.
What happens if I lose the encryption key?
n8n uses it to encrypt credentials, so back it up. The documentation does not describe a recovery process, so do not rely on resetting it.
Can I turn off telemetry?
Yes. Set N8N_DIAGNOSTICS_ENABLED to false. That also disables Ask AI in the Code node.
Related
Sources
Need this built or fixed?
Start a proposal and our EU-sovereign team will scope it with you.
Start a proposal →