Context
The stack currently has Pi-hole, Traefik, Homepage, Jellyfin, Portainer, Syncthing, and FileBrowser. This issue adds Netdata for host-level monitoring.
Key architectural constraint: Netdata must use network_mode: host so it can access /proc, /sys, and Docker socket for metrics. This means it cannot use Docker label-based Traefik routing — instead it gets a file in traefik/dynamic/ pointing to host.docker.internal, the same pattern as Pi-hole's traefik/dynamic/services.yml.
Files to create/modify
- Create
traefik/dynamic/netdata.yml
- Modify
docker-compose.yml — add netdata service + add extra_hosts to homepage service
- Modify
homepage/config/services.yaml — add Netdata entry under a new "Monitoring" group
Implementation details
docker-compose.yml — netdata service
netdata:
container_name: netdata
image: netdata/netdata:stable
network_mode: host
pid: host
cap_add:
- SYS_PTRACE
- SYS_ADMIN
security_opt:
- apparmor:unconfined
volumes:
- netdataconfig:/etc/netdata
- netdatalib:/var/lib/netdata
- netdatacache:/var/cache/netdata
- /etc/passwd:/host/etc/passwd:ro
- /etc/group:/host/etc/group:ro
- /etc/localtime:/etc/localtime:ro
- /etc/os-release:/host/etc/os-release:ro
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/host/root:ro,rslave
- /var/log:/host/var/log:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /run/dbus:/run/dbus:ro
restart: unless-stopped
Also add named volumes at the bottom of docker-compose.yml:
volumes:
netdataconfig:
netdatalib:
netdatacache:
docker-compose.yml — homepage service
Add extra_hosts so the homepage widget can reach Netdata over host network:
extra_hosts:
- "host.docker.internal:host-gateway"
traefik/dynamic/netdata.yml
http:
routers:
netdata:
rule: "Host(`netdata.woggles.work`)"
entryPoints:
- websecure
tls:
certResolver: cloudflare
service: netdata-svc
services:
netdata-svc:
loadBalancer:
servers:
- url: "http://host.docker.internal:19999"
homepage/config/services.yaml — new Monitoring group
Add at the bottom (after Files):
- Monitoring:
- Netdata:
href: https://netdata.woggles.work
description: Host and container metrics
icon: netdata
widget:
type: netdata
url: http://host.docker.internal:19999
fields: ["warnings", "criticals"]
No HOMEPAGE_VAR_* needed — Netdata widget requires no API key. Do not add any env var wiring for it.
No .env.example changes needed
Netdata needs no env vars.
Testing strategy
- Run
./scripts/lint-config.sh — must exit 0 before opening a PR.
- Check
docker-compose.yml for:
network_mode: host on netdata (no networks: key)
extra_hosts block present on homepage service
- Named volumes
netdataconfig, netdatalib, netdatacache declared at the top-level volumes: section
- No Traefik labels on the netdata container
- Check
traefik/dynamic/netdata.yml matches the Pi-hole pattern in traefik/dynamic/services.yml.
- Check
homepage/config/services.yaml — Netdata widget URL uses host.docker.internal:19999 (not a container name, not LAN IP).
- Security review: no secrets introduced (Netdata widget needs no API key);
apparmor:unconfined and SYS_PTRACE/SYS_ADMIN caps are required by Netdata on Ubuntu and are expected.
- README / scripts check:
./scripts/lint-config.sh covers env var wiring; no README update needed unless a new setup step is documented.
- Full code review before opening PR — confirm no unrelated files changed.
Before opening the PR
- Run
./scripts/lint-config.sh — must exit 0.
- Open the PR against
main from a feature branch.
Context
The stack currently has Pi-hole, Traefik, Homepage, Jellyfin, Portainer, Syncthing, and FileBrowser. This issue adds Netdata for host-level monitoring.
Key architectural constraint: Netdata must use
network_mode: hostso it can access/proc,/sys, and Docker socket for metrics. This means it cannot use Docker label-based Traefik routing — instead it gets a file intraefik/dynamic/pointing tohost.docker.internal, the same pattern as Pi-hole'straefik/dynamic/services.yml.Files to create/modify
traefik/dynamic/netdata.ymldocker-compose.yml— addnetdataservice + addextra_hoststohomepageservicehomepage/config/services.yaml— add Netdata entry under a new "Monitoring" groupImplementation details
docker-compose.yml— netdata serviceAlso add
named volumesat the bottom of docker-compose.yml:docker-compose.yml— homepage serviceAdd
extra_hostsso the homepage widget can reach Netdata over host network:traefik/dynamic/netdata.ymlhomepage/config/services.yaml— new Monitoring groupAdd at the bottom (after Files):
No
HOMEPAGE_VAR_*needed — Netdata widget requires no API key. Do not add any env var wiring for it.No
.env.examplechanges neededNetdata needs no env vars.
Testing strategy
./scripts/lint-config.sh— must exit 0 before opening a PR.docker-compose.ymlfor:network_mode: hoston netdata (nonetworks:key)extra_hostsblock present on homepage servicenetdataconfig,netdatalib,netdatacachedeclared at the top-levelvolumes:sectiontraefik/dynamic/netdata.ymlmatches the Pi-hole pattern intraefik/dynamic/services.yml.homepage/config/services.yaml— Netdata widget URL useshost.docker.internal:19999(not a container name, not LAN IP).apparmor:unconfinedandSYS_PTRACE/SYS_ADMINcaps are required by Netdata on Ubuntu and are expected../scripts/lint-config.shcovers env var wiring; no README update needed unless a new setup step is documented.Before opening the PR
./scripts/lint-config.sh— must exit 0.mainfrom a feature branch.