Skip to content

Commit f58555c

Browse files
authored
Merge pull request #39 from joshdev8/feat/monitoring-stack
Add Prometheus, cAdvisor, and node-exporter to monitoring stack
2 parents 3a07357 + 1f479c1 commit f58555c

5 files changed

Lines changed: 102 additions & 69 deletions

File tree

CLAUDE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ There is no test suite. After changing `docker-compose.yml`, always run `docker
2323

2424
**Network isolation matters.** Services are split across four bridge networks and one host-mode service. A service can only reach another if they share a network — adding a new service requires picking the right one (or declaring multiple):
2525

26-
- `monitoring_network` — tautulli, grafana, telegraf, watchtower, portainer
26+
- `monitoring_network` — tautulli, grafana, telegraf, watchtower, portainer, prometheus, cadvisor, node-exporter
2727
- `media_network` — seerr, radarr, sonarr, prowlarr, bazarr
2828
- `download_network` — transmission, watchlistarr, cleanarr, requestrr, radarr, sonarr
2929
- `tracearr-network` — tracearr, timescale (PostgreSQL), redis
@@ -37,7 +37,9 @@ Radarr and Sonarr are deliberately on both `media_network` (so Seerr, Prowlarr,
3737

3838
**Volume paths are intentionally user-specific.** All bind mounts are rooted at `${USERDIR}` from `.env`. When advising the user, do not assume any particular host path layout — the README explicitly tells them to update paths to match their drive mounts.
3939

40-
**No Prometheus in the stack.** There is no `prometheus` service in `docker-compose.yml`. A starting-point config lives at `docs/prometheus.example.yml` for users who want to add Prometheus themselves — don't assume metrics are being scraped today.
40+
**Prometheus is live, but only cAdvisor + node-exporter feed it.** `prometheus/prometheus.yml` is mounted into the prometheus container; only the `cadvisor` and `node_exporter` scrape jobs are active. The `telegraf` and `tautulli` jobs are commented out because those containers don't expose a `/metrics` endpoint by default — telegraf would need the `prometheus_client` output plugin enabled, and Tautulli needs a metrics plugin installed. Grafana points at Prometheus the same way it would point at any data source — configure it in the Grafana UI after first boot.
41+
42+
**cAdvisor needs `privileged: true` and several host-fs mounts.** This is the standard cAdvisor pattern; flag it if a user reports security concerns about the monitoring stack. It also binds host port `8080` — if a user has something else on `8080`, that's the conflict.
4143

4244
**Transmission uses `haugene/transmission-openvpn` and won't start without VPN credentials.** The container runs an OpenVPN client internally; `OPENVPN_PROVIDER`, `OPENVPN_CONFIG`, `OPENVPN_USERNAME`, and `OPENVPN_PASSWORD` must all be set in `.env`. The compose service declares `cap_add: NET_ADMIN` and `devices: /dev/net/tun` for the OpenVPN client; the data volume is `/data` (haugene's convention), not `/config` like the linuxserver image. `LOCAL_NETWORK` (CIDR, default `192.168.0.0/16`) controls which destinations bypass the tunnel — if a user reports the web UI is unreachable, this is almost always the cause.
4345

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ flowchart LR
9595
9696
Telegraf -->|host + container metrics| Grafana
9797
Tautulli -->|usage data| Grafana
98+
99+
cAdvisor -->|container metrics| Prometheus
100+
NodeExporter[node-exporter] -->|host metrics| Prometheus
101+
Prometheus -->|scraped time-series| Grafana
98102
```
99103

100104
See [Network Architecture](#network-architecture) below for the exact network membership of each service.
@@ -143,6 +147,9 @@ A ready-to-use [Kometa](https://kometa.wiki/) (Plex Meta Manager) configuration
143147
|---------|-------------|------|
144148
| [Tautulli](https://tautulli.com/) | Plex usage monitoring | `8181` |
145149
| [Grafana](https://grafana.com/) | Metrics visualization | `3000` |
150+
| [Prometheus](https://prometheus.io/) | Time-series metrics database — scrapes cAdvisor + node-exporter | `9090` |
151+
| [cAdvisor](https://github.com/google/cadvisor) | Per-container CPU / memory / network metrics | `8080` |
152+
| [node-exporter](https://github.com/prometheus/node_exporter) | Host (CPU / disk / network) metrics | `9100` |
146153
| [Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) | Metrics collection agent | N/A |
147154
| [Tracearr](https://github.com/connorgallopo/tracearr) | Stream tracking and account sharing detection | `3001` |
148155
| [Portainer](https://www.portainer.io/) | Docker management UI ([note on socket access](#a-note-on-portainer)) | `9000` |
@@ -166,7 +173,7 @@ These services pair well with this stack but are not included in the default `do
166173

167174
Services are isolated into separate Docker networks:
168175

169-
- **`monitoring_network`** - Tautulli, Grafana, Telegraf, Watchtower, Portainer
176+
- **`monitoring_network`** - Tautulli, Grafana, Telegraf, Watchtower, Portainer, Prometheus, cAdvisor, node-exporter
170177
- **`media_network`** - Seerr, Radarr, Sonarr, Prowlarr, Bazarr
171178
- **`download_network`** - Transmission, Watchlistarr, Cleanarr, Requestrr, Radarr, Sonarr
172179
- **`tracearr-network`** - Tracearr, TimescaleDB, Redis

docker-compose.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,62 @@ services:
8383
- portainer_data:/data
8484
restart: unless-stopped
8585

86+
prometheus:
87+
container_name: prometheus
88+
image: prom/prometheus:latest
89+
networks:
90+
- monitoring_network
91+
ports:
92+
- "9090:9090"
93+
environment:
94+
- TZ=${TZ}
95+
command:
96+
- "--config.file=/etc/prometheus/prometheus.yml"
97+
- "--storage.tsdb.path=/prometheus"
98+
volumes:
99+
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
100+
- prometheus_data:/prometheus
101+
restart: unless-stopped
102+
103+
# Container resource metrics for Prometheus. Reads the Docker socket
104+
# read-only and several host filesystems to enumerate running containers.
105+
cadvisor:
106+
container_name: cadvisor
107+
image: gcr.io/cadvisor/cadvisor:latest
108+
networks:
109+
- monitoring_network
110+
ports:
111+
- "8080:8080"
112+
volumes:
113+
- /:/rootfs:ro
114+
- /var/run:/var/run:ro
115+
- /sys:/sys:ro
116+
- /var/lib/docker/:/var/lib/docker:ro
117+
- /dev/disk/:/dev/disk:ro
118+
devices:
119+
- /dev/kmsg
120+
privileged: true
121+
restart: unless-stopped
122+
123+
# Host (kernel / disk / network) metrics for Prometheus.
124+
node-exporter:
125+
container_name: node-exporter
126+
image: prom/node-exporter:latest
127+
networks:
128+
- monitoring_network
129+
ports:
130+
- "9100:9100"
131+
command:
132+
- "--path.procfs=/host/proc"
133+
- "--path.sysfs=/host/sys"
134+
- "--path.rootfs=/rootfs"
135+
- "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)"
136+
volumes:
137+
- /proc:/host/proc:ro
138+
- /sys:/host/sys:ro
139+
- /:/rootfs:ro
140+
restart: unless-stopped
141+
86142
# ============ MEDIA MANAGEMENT ============
87143
seerr:
88144
image: ghcr.io/seerr-team/seerr:latest
@@ -318,5 +374,6 @@ volumes:
318374
prowlarr:
319375
bazarr:
320376
portainer_data:
377+
prometheus_data:
321378
timescale_data:
322379
redis_data:

docs/prometheus.example.yml

Lines changed: 0 additions & 66 deletions
This file was deleted.

prometheus/prometheus.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
global:
2+
scrape_interval: 15s
3+
evaluation_interval: 15s
4+
5+
alerting:
6+
alertmanagers:
7+
- static_configs:
8+
- targets:
9+
# - alertmanager:9093
10+
11+
scrape_configs:
12+
# Container resource metrics via cAdvisor
13+
- job_name: "cadvisor"
14+
static_configs:
15+
- targets: ["cadvisor:8080"]
16+
17+
# Host metrics (CPU, memory, disk, network) via node_exporter
18+
- job_name: "node_exporter"
19+
static_configs:
20+
- targets: ["node-exporter:9100"]
21+
22+
# Telegraf — uncomment after enabling the prometheus_client output plugin in
23+
# telegraf.conf. The container doesn't expose :9273 by default.
24+
# - job_name: "telegraf"
25+
# static_configs:
26+
# - targets: ["telegraf:9273"]
27+
28+
# Tautulli — uncomment after installing a Prometheus metrics plugin in
29+
# Tautulli. The base container does not expose /metrics natively.
30+
# - job_name: "tautulli"
31+
# metrics_path: "/metrics"
32+
# static_configs:
33+
# - targets: ["tautulli:8181"]

0 commit comments

Comments
 (0)