I’ve tried to make the default docker n8n + traefik setup a bit more secure.
By doing so, I think I broke something.
On a rootless docker, that’s my yml file:
volumes:
n8n_storage:
traefik_storage:
services:
traefik:
image: "traefik"
restart: always
command:
- "--api.dashboard=true"
- --log.level=INFO
- --accesslog=true
- "--api=true"
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:8140"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:8143"
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
- "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
- "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.mytlschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true"
ports:
- "8140:80"
- "8143:443"
volumes:
- ./traefik_storage/letsencrypt:/letsencrypt
- ./traefik/config:/etc/traefik/dynamic
- /run/user/1001/docker.sock:/var/run/docker.sock:ro
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "127.0.0.1:5678:5678"
labels:
- traefik.enable=true
- traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
- traefik.http.routers.n8n.tls=true
- traefik.http.routers.n8n.entrypoints=websecure
- traefik.http.routers.n8n.tls.certresolver=mytlschallenge
- traefik.http.middlewares.n8n.headers.SSLRedirect=true
- traefik.http.middlewares.n8n.headers.STSSeconds=315360000
- traefik.http.middlewares.n8n.headers.browserXSSFilter=true
- traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
- traefik.http.middlewares.n8n.headers.forceSTSHeader=true
- traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
- traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
- traefik.http.middlewares.n8n.headers.STSPreload=true
- traefik.http.routers.n8n.middlewares=n8n@docker
- traefik.http.routers.mydashboard.rule=Host(`${TRAEFIK_SUBDOMAIN}.${DOMAIN_NAME}`)
- traefik.http.routers.mydashboard.service=api@internal
- "traefik.http.middlewares.myauth.basicauth.users=${TRAEFIK_BASIC_AUTH_USER}:${TRAEFIK_BASIC_AUTH_PASSWORD}"
- "traefik.http.routers.mydashboard.middlewares=myauth@docker"
environment:
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
# Enable authentication
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
# Secure credentials with encryption
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
# Disable the public API https://docs.n8n.io/hosting/securing/disable-public-api/
- N8N_PUBLIC_API_DISABLED=true
- N8N_PUBLIC_API_SWAGGERUI_DISABLED=true
# Disable data collection https://docs.n8n.io/hosting/securing/telemetry-opt-out/#collected-data
- N8N_DIAGNOSTICS_ENABLED=false
- N8N_VERSION_NOTIFICATIONS_ENABLED=false
- N8N_TEMPLATES_ENABLED=false
volumes:
- ./n8n_storage:/home/node/.n8n
- ./n8n-local-files:/files
deploy:
resources:
limits:
cpus: '2.0'
memory: 3G
These are the log:
$ docker compose logs traefik
WARN[0000] The "apr1" variable is not set. Defaulting to a blank string.
WARN[0000] The "n4729mxb" variable is not set. Defaulting to a blank string.
WARN[0000] The "apr1" variable is not set. Defaulting to a blank string.
WARN[0000] The "n4729mxb" variable is not set. Defaulting to a blank string.
WARN[0000] The "apr1" variable is not set. Defaulting to a blank string.
WARN[0000] The "n4729mxb" variable is not set. Defaulting to a blank string.
WARN[0000] The "apr1" variable is not set. Defaulting to a blank string.
WARN[0000] The "n4729mxb" variable is not set. Defaulting to a blank string.
traefik-1 | 2025-03-12T07:11:59Z INF Traefik version 3.3.4 built on 2025-02-25T10:11:01Z version=3.3.4
traefik-1 | 2025-03-12T07:11:59Z INF
traefik-1 | Stats collection is disabled.
traefik-1 | Help us improve Traefik by turning this feature on :)
traefik-1 | More details on: https://doc.traefik.io/traefik/contributing/data-collection/
traefik-1 |
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider aggregator *aggregator.ProviderAggregator
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider *file.Provider
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider *traefik.Provider
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider *docker.Provider
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider *acme.ChallengeTLSALPN
traefik-1 | 2025-03-12T07:11:59Z INF Starting provider *acme.Provider
traefik-1 | 2025-03-12T07:11:59Z INF Testing certificate renew... acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory providerName=mytlschallenge.acme
traefik-1 | 2025-03-12T07:12:09Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
traefik-1 | 2025-03-12T07:12:10Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:16Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:17Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
traefik-1 | 2025-03-12T07:12:21Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:26Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
traefik-1 | 2025-03-12T07:12:27Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:33Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:33Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
traefik-1 | 2025-03-12T07:12:41Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:42Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
traefik-1 | 2025-03-12T07:12:52Z ERR error="service \"n8n-docker-n8n\" error: unable to find the IP address for the container \"/docker_n8n-n8n-1\": the server is ignored" container=n8n-docker-n8n-f74f85601a0b0981d4c8280925a38d75d321f454b501b9f414b92037dffd62b8 providerName=docker
traefik-1 | 2025-03-12T07:12:56Z ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [sub.domain.de]: error: one or more domains had a problem:\n[sub.domain.de] invalid authorization: acme: error: 400 :: urn:ietf:params:acme:error:connection :: 5.189.164.68: Connection refused\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["sub.domain.de"] providerName=mytlschallenge.acme routerName=n8n@docker rule=Host(`sub.domain.de`)
The warnings seem to come from the traefik dashboard auth.
Can’t get them to work - found several hints with $ and $$. But it’s only warning, so I hope it’s save to ignore it for now?
ping sub.domain.de
resolves correctly to my server IP - since a few days already.
$ docker network inspect docker_n8n_default
[
{
"Name": "docker_n8n_default",
"Id": "16bca091a9abdca68a7d1bcec2309e9406be7a5b5f3d2acb552c0cb14dbc56b7",
"Created": "2025-03-12T08:11:58.283728977+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"13d9afbab9014455bcff46c2c438a3b18b4787861a5685483c67d0723100ad50": {
"Name": "docker_n8n-traefik-1",
"EndpointID": "538a725569495e00d3ce398f9550fe4c2f31e513fcce5faf15c5ef30bd949d03",
"MacAddress": "52:b2:b7:9c:2d:e7",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.config-hash": "82c611e68d66025c5ef0e83db86b44807a2e91129f99ed5f296f771d03c5fc30",
"com.docker.compose.network": "default",
"com.docker.compose.project": "docker_n8n",
"com.docker.compose.version": "2.33.1"
}
}
]
it seems as if n8n isn't connected to the network with traefik?
Shall I add networks manually in the composer yml file? (why are there none in the instruction? https://docs.n8n.io/hosting/installation/server-setups/docker-compose/#5-create-docker-compose-file )
I had to change to the acme staging server due to too many tries.
Should I still be able to access n8n via the browser?
At the moment I get from my browser:
Secure Connection Failed
An error occurred during a connection to subdomain.domain.de:8143. PR_END_OF_FILE_ERROR
Error code: PR_END_OF_FILE_ERROR
Information on your n8n setup
- n8n version: latest
- Database (default: SQLite): SQLite
- n8n EXECUTIONS_PROCESS setting (default: own, main): own
- Running n8n via (Docker, npm, n8n cloud, desktop app): docker
- Operating system: Ubuntu 24.04 LTS