Compare commits
No commits in common. "b35165cf0b34dcb44047849dfd1befb794ede27e" and "75357d31a2900e46e92ccff441ae1dda5892bec5" have entirely different histories.
b35165cf0b
...
75357d31a2
20
.env.example
Normal file
20
.env.example
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# ---- Port Bindings ----
|
||||||
|
PROMETHEUS_PORT=9390
|
||||||
|
ALERTMANAGER_PORT=9043
|
||||||
|
LOKI_PORT=4100
|
||||||
|
NODE_EXPORTER_PORT=9112
|
||||||
|
DOCKER_EXPORTER_PORT=9487
|
||||||
|
PIHOLE_WEB_PORT=8040
|
||||||
|
PIHOLE_DNS_PORT=53
|
||||||
|
PIHOLE_HTTPS_PORT=443
|
||||||
|
|
||||||
|
# ---- Pihole Config ----
|
||||||
|
PIHOLE_PASSWORD=
|
||||||
|
TZ=America/Toronto
|
||||||
|
WEBPASSWORD=
|
||||||
|
|
||||||
|
# ---- Alertmanager ----
|
||||||
|
DISCORD_WEBHOOK=
|
||||||
|
|
||||||
|
# ---- Metadata ----
|
||||||
|
HOSTNAME=
|
||||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -0,0 +1 @@
|
||||||
|
.env
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
services:
|
|
||||||
# --- MONGODB ---
|
|
||||||
mongodb:
|
|
||||||
image: mongo:7
|
|
||||||
container_name: mongodb
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "27017:27017"
|
|
||||||
volumes:
|
|
||||||
- ./mongo-data:/data/db
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
# --- POSTGRESQL ---
|
|
||||||
postgres:
|
|
||||||
image: postgres:16
|
|
||||||
container_name: postgres
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=mystic_admin
|
|
||||||
- POSTGRES_PASSWORD=Nyhjew-didvot-zypsa7
|
|
||||||
- POSTGRES_DB=postgres
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
volumes:
|
|
||||||
- ./postgres-data:/var/lib/postgresql/data
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
# --- KOMODO AGENT (PERIPHERY) ---
|
|
||||||
komodo-periphery:
|
|
||||||
image: ghcr.io/moghtech/komodo-periphery:2
|
|
||||||
container_name: komodo-periphery
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
# The Tailscale IP of VM1 (The Brain)
|
|
||||||
PERIPHERY_CORE_ADDRESS: 100.80.179.128:9120
|
|
||||||
# The name that will appear in your Komodo Web UI
|
|
||||||
PERIPHERY_CONNECT_AS: Mystic-Databases
|
|
||||||
# Your Onboarding Key from the UI
|
|
||||||
PERIPHERY_ONBOARDING_KEY: O_dPWwdaJNO7q87kgvPE4hnjaLlcsu_O
|
|
||||||
PERIPHERY_SERVER_ENABLED: "true"
|
|
||||||
# Recommended for correct disk reporting
|
|
||||||
PERIPHERY_INCLUDE_DISK_MOUNTS: /etc/hostname
|
|
||||||
ports:
|
|
||||||
- "8120:8120"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- ./komodo:/config
|
|
||||||
- /proc:/proc:ro
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
# --- MONITORING EXPORTERS (Scraped by VM1) ---
|
|
||||||
node-exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: node-exporter
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9100:9100"
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:latest
|
|
||||||
container_name: cadvisor
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:ro
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker/:/var/lib/docker:ro
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
postgres-exporter:
|
|
||||||
image: prometheuscommunity/postgres-exporter
|
|
||||||
container_name: postgres-exporter
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- DATA_SOURCE_NAME=postgresql://mystic_admin:your_secure_password@postgres:5432/postgres?sslmode=disable
|
|
||||||
ports:
|
|
||||||
- "9187:9187"
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
mongodb-exporter:
|
|
||||||
image: percona/mongodb_exporter:0.40
|
|
||||||
container_name: mongodb-exporter
|
|
||||||
restart: always
|
|
||||||
command:
|
|
||||||
- '--mongodb.uri=mongodb://mongodb:27017'
|
|
||||||
ports:
|
|
||||||
- "9216:9216"
|
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
|
|
||||||
networks:
|
|
||||||
db-net:
|
|
||||||
driver: bridge
|
|
||||||
124
docs.md
Normal file
124
docs.md
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# 🧠 Infrastructure Usage Guide
|
||||||
|
|
||||||
|
This guide explains how to use the new Docker-based infrastructure stack deployed on **Unraid**, **Raspberry Pi**, and **Ubuntu**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Starting the Monitoring Stack
|
||||||
|
|
||||||
|
Each machine has a `start.sh` wrapper script that:
|
||||||
|
- Runs `docker compose up -d`
|
||||||
|
- Waits a few seconds for container readiness
|
||||||
|
- Logs container IPs, ports, and web URLs
|
||||||
|
|
||||||
|
To start:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x start.sh
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 Service Overview
|
||||||
|
|
||||||
|
The following services are deployed (excluding Pi-hole on Ubuntu):
|
||||||
|
|
||||||
|
| Service | Unraid | Pi | Ubuntu |
|
||||||
|
|------------------|--------|----|-------|
|
||||||
|
| Grafana | ✅ | ❌ | ❌ |
|
||||||
|
| Prometheus | ✅ | ✅ | ✅ |
|
||||||
|
| Loki | ✅ | ✅ | ✅ |
|
||||||
|
| Promtail | ✅ | ✅ | ✅ |
|
||||||
|
| Alertmanager | ✅ | ✅ | ✅ |
|
||||||
|
| Node Exporter | ✅ | ✅ | ✅ |
|
||||||
|
| Docker Exporter | ✅ | ✅ | ✅ |
|
||||||
|
| NGINX | ✅ | ❌ | ❌ |
|
||||||
|
| Pi-hole | ❌ | ✅ | ❌ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Defining IPs in Pi-hole
|
||||||
|
|
||||||
|
Pi-hole is used for internal DNS routing of your infrastructure services.
|
||||||
|
|
||||||
|
1. Open the **Pi-hole Admin Panel**
|
||||||
|
2. Go to **Local DNS > DNS Records**
|
||||||
|
3. Add A records like:
|
||||||
|
|
||||||
|
```
|
||||||
|
grafana.wyvern.bray.io -> 192.168.2.16
|
||||||
|
prometheus.unraid.bray.io -> 192.168.2.28
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 You can verify entries with `dig grafana.wyvern.bray.io`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Defining IPs in NGINX
|
||||||
|
|
||||||
|
NGINX is used to expose internal services via friendly URLs (e.g. `https://grafana.wyvern.bray.io`).
|
||||||
|
|
||||||
|
1. Go to: `configs/nginx/conf.d/`
|
||||||
|
2. Create or modify `.conf` files like:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name grafana.wyvern.bray.io;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://192.168.2.16:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Reload NGINX (or restart the container):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker restart nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Adding New Services
|
||||||
|
|
||||||
|
1. Add a new service to `docker-compose.yml`
|
||||||
|
2. Assign a static IP if needed
|
||||||
|
3. Add a DNS record in Pi-hole
|
||||||
|
4. Add a reverse proxy entry in NGINX
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧼 Resetting the Stack
|
||||||
|
|
||||||
|
You can bring down and rebuild everything:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
This will recreate containers with preserved volumes. If you wipe volumes, services will reset.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Final Tip: Keep a Network Sheet
|
||||||
|
|
||||||
|
Keep a `infra-ip-map.md` or spreadsheet like:
|
||||||
|
|
||||||
|
| Container | Host | Static IP | Port | Domain |
|
||||||
|
|----------------|---------|----------------|------|-----------------------------------|
|
||||||
|
| Grafana | Unraid | 192.168.2.16 | 3000 | grafana.wyvern.bray.io |
|
||||||
|
| Prometheus | Pi | 192.168.2.28 | 9090 | prometheus.pi.bray.io |
|
||||||
|
| Loki | Ubuntu | 192.168.2.26 | 3100 | loki.ubuntu.bray.io |
|
||||||
|
| ... | ... | ... | ... | ... |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Happy hacking 🛠️
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
services:
|
|
||||||
# --- THE FORGE ---
|
|
||||||
forgejo:
|
|
||||||
image: codeberg.org/forgejo/forgejo:7
|
|
||||||
container_name: forgejo
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- FORGEJO__database__DB_TYPE=postgres
|
|
||||||
- FORGEJO__database__HOST=100.109.59.41:5432
|
|
||||||
- FORGEJO__database__NAME=forgejodb
|
|
||||||
- FORGEJO__database__USER=forgejodb
|
|
||||||
- FORGEJO__database__PASSWD=Nyhjew-didvot-zypsa7 # Must match VM3 setup
|
|
||||||
- FORGEJO__metrics__ENABLED=true # Enables internal exporter
|
|
||||||
- FORGEJO__metrics__TOKEN=mystic_metrics_token # Security for metrics
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
- "2222:22"
|
|
||||||
volumes:
|
|
||||||
- ./data:/data
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
networks:
|
|
||||||
- git-net
|
|
||||||
|
|
||||||
# --- KOMODO AGENT (PERIPHERY) ---
|
|
||||||
komodo-periphery:
|
|
||||||
image: ghcr.io/moghtech/komodo-periphery:2
|
|
||||||
container_name: komodo-periphery
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
PERIPHERY_CORE_ADDRESS: 100.80.179.128:9120
|
|
||||||
PERIPHERY_CONNECT_AS: Mystic-Git
|
|
||||||
PERIPHERY_ONBOARDING_KEY: O_dPWwdaJNO7q87kgvPE4hnjaLlcsu_O
|
|
||||||
PERIPHERY_SERVER_ENABLED: "true"
|
|
||||||
PERIPHERY_INCLUDE_DISK_MOUNTS: /etc/hostname
|
|
||||||
ports:
|
|
||||||
- "8120:8120"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- ./komodo:/config
|
|
||||||
- /proc:/proc:ro
|
|
||||||
networks:
|
|
||||||
- git-net
|
|
||||||
|
|
||||||
# --- MONITORING ---
|
|
||||||
node-exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: node-exporter
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9100:9100"
|
|
||||||
networks:
|
|
||||||
- git-net
|
|
||||||
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:latest
|
|
||||||
container_name: cadvisor
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:ro
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker/:/var/lib/docker:ro
|
|
||||||
networks:
|
|
||||||
- git-net
|
|
||||||
|
|
||||||
networks:
|
|
||||||
git-net:
|
|
||||||
driver: bridge
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
services:
|
|
||||||
# --- ORCHESTRATION (The Brain) ---
|
|
||||||
komodo-core:
|
|
||||||
image: ghcr.io/moghtech/komodo-core:2
|
|
||||||
container_name: komodo-core
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9120:9120"
|
|
||||||
environment:
|
|
||||||
- KOMODO_DATABASE_ADDRESS=l100.109.59.41:27017
|
|
||||||
volumes:
|
|
||||||
- ./komodo:/config
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
|
|
||||||
# --- MONITORING (The Eyes) ---
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:latest
|
|
||||||
container_name: prometheus
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9090:9090"
|
|
||||||
volumes:
|
|
||||||
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
|
|
||||||
- prometheus_data:/prometheus
|
|
||||||
command:
|
|
||||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
|
||||||
- '--storage.tsdb.path=/prometheus'
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:latest
|
|
||||||
container_name: grafana
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3001:3000"
|
|
||||||
volumes:
|
|
||||||
- grafana_data:/var/lib/grafana
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
|
|
||||||
# --- EXPORTERS (The Sensors) ---
|
|
||||||
node-exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: node-exporter
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9110:9100" # Mapped to 9110 to avoid any host conflicts
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:latest
|
|
||||||
container_name: cadvisor
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:ro
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker/:/var/lib/docker:ro
|
|
||||||
- /dev/disk/:/dev/disk:ro
|
|
||||||
networks:
|
|
||||||
- monitor-net
|
|
||||||
|
|
||||||
networks:
|
|
||||||
monitor-net:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus_data:
|
|
||||||
grafana_data:
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
# --- VM1: MYSTIC-CLOUD (Local) ---
|
|
||||||
- job_name: 'cloud-node'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['node-exporter:9100']
|
|
||||||
|
|
||||||
- job_name: 'cloud-docker'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['cadvisor:8080']
|
|
||||||
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
# --- VM3: MYSTIC-DATABASES (Remote via Tailscale) ---
|
|
||||||
- job_name: 'vm3-node'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['100.109.59.41:9100']
|
|
||||||
|
|
||||||
- job_name: 'vm3-docker'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['100.109.59.41:8080']
|
|
||||||
|
|
||||||
- job_name: 'vm3-postgres'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['100.109.59.41:9187']
|
|
||||||
|
|
||||||
- job_name: 'vm3-mongo'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['100.109.59.41:9216']
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
services:
|
|
||||||
node-exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: node-exporter
|
|
||||||
volumes:
|
|
||||||
- /proc:/host/proc:ro
|
|
||||||
- /sys:/host/sys:ro
|
|
||||||
- /:/rootfs:ro
|
|
||||||
command:
|
|
||||||
- '--path.procfs=/host/proc'
|
|
||||||
- '--path.rootfs=/rootfs'
|
|
||||||
- '--path.sysfs=/host/sys'
|
|
||||||
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
|
|
||||||
ports:
|
|
||||||
- "9100:9100"
|
|
||||||
restart: unless-stopped
|
|
||||||
19
pi/Dockerfile.alertmanager
Normal file
19
pi/Dockerfile.alertmanager
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Stage 1: Pull original Alertmanager binary
|
||||||
|
FROM prom/alertmanager:latest as upstream
|
||||||
|
|
||||||
|
# Stage 2: Alpine + envsubst
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install envsubst and ca-certificates
|
||||||
|
RUN apk add --no-cache gettext ca-certificates
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
RUN mkdir -p /etc/alertmanager /alertmanager
|
||||||
|
|
||||||
|
# Copy Alertmanager binary from upstream
|
||||||
|
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
||||||
|
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
||||||
|
|
||||||
|
# Default config will be overwritten by volume mount
|
||||||
|
ENTRYPOINT ["/bin/sh", "-c"]
|
||||||
|
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
||||||
14
pi/configs/alertmanager/alertmanager.template.yml
Normal file
14
pi/configs/alertmanager/alertmanager.template.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
14
pi/configs/alertmanager/alertmanager.yml
Normal file
14
pi/configs/alertmanager/alertmanager.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
53
pi/configs/loki/loki-config.yml
Normal file
53
pi/configs/loki/loki-config.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9095
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
lifecycler:
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
chunk_idle_period: 5m
|
||||||
|
chunk_retain_period: 30s
|
||||||
|
wal:
|
||||||
|
dir: /loki/wal
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
allow_structured_metadata: false
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v12
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: /loki/index
|
||||||
|
cache_location: /loki/cache
|
||||||
|
filesystem:
|
||||||
|
directory: /loki/chunks
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: /loki/rules
|
||||||
|
rule_path: /loki/rules-temp
|
||||||
|
alertmanager_url: http://localhost:9093
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
19
pi/configs/prometheus/prometheus.yml
Normal file
19
pi/configs/prometheus/prometheus.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9090']
|
||||||
|
|
||||||
|
- job_name: 'node_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9100']
|
||||||
|
|
||||||
|
- job_name: 'docker_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9487']
|
||||||
|
|
||||||
|
- job_name: 'pi_services'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:3100', 'localhost:9093']
|
||||||
9
pi/configs/promtail/positions.yaml
Normal file
9
pi/configs/promtail/positions.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
positions:
|
||||||
|
/var/log/alf.log: "0"
|
||||||
|
/var/log/fsck_apfs.log: "23880"
|
||||||
|
/var/log/fsck_apfs_error.log: "676"
|
||||||
|
/var/log/fsck_hfs.log: "4044"
|
||||||
|
/var/log/install.log: "3800109"
|
||||||
|
/var/log/shutdown_monitor.log: "1971"
|
||||||
|
/var/log/system.log: "6132"
|
||||||
|
/var/log/wifi.log: "1107090"
|
||||||
18
pi/configs/promtail/promtail.yml
Normal file
18
pi/configs/promtail/promtail.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
server:
|
||||||
|
http_listen_port: 9080
|
||||||
|
grpc_listen_port: 0
|
||||||
|
|
||||||
|
positions:
|
||||||
|
filename: /etc/promtail/positions.yaml
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- url: http://loki:3100/loki/api/v1/push
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: system
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: varlogs
|
||||||
|
__path__: /var/log/*.log
|
||||||
87
pi/docker-compose.yml
Normal file
87
pi/docker-compose.yml
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
container_name: ${HOSTNAME}-prometheus
|
||||||
|
ports:
|
||||||
|
- "${PROMETHEUS_PORT}:9090"
|
||||||
|
volumes:
|
||||||
|
- ./configs/prometheus:/etc/prometheus
|
||||||
|
- prometheus-data:/prometheus
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
alertmanager:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.alertmanager
|
||||||
|
container_name: ${HOSTNAME}-alertmanager
|
||||||
|
ports:
|
||||||
|
- "${ALERTMANAGER_PORT}:9093"
|
||||||
|
volumes:
|
||||||
|
- ./configs/alertmanager:/etc/alertmanager
|
||||||
|
environment:
|
||||||
|
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:latest
|
||||||
|
container_name: ${HOSTNAME}-loki
|
||||||
|
ports:
|
||||||
|
- "${LOKI_PORT}:3100"
|
||||||
|
volumes:
|
||||||
|
- ./configs/loki:/etc/loki
|
||||||
|
- loki-data:/loki
|
||||||
|
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
promtail:
|
||||||
|
image: grafana/promtail:latest
|
||||||
|
container_name: ${HOSTNAME}-promtail
|
||||||
|
volumes:
|
||||||
|
- /var/log:/var/log:ro
|
||||||
|
- ./configs/promtail:/etc/promtail
|
||||||
|
command: -config.file=/etc/promtail/promtail.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
node_exporter:
|
||||||
|
image: prom/node-exporter:latest
|
||||||
|
container_name: ${HOSTNAME}-node_exporter
|
||||||
|
ports:
|
||||||
|
- "${NODE_EXPORTER_PORT}:9100"
|
||||||
|
command:
|
||||||
|
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
docker_exporter:
|
||||||
|
image: prometheusnet/docker_exporter
|
||||||
|
container_name: ${HOSTNAME}-docker_exporter
|
||||||
|
ports:
|
||||||
|
- "${DOCKER_EXPORTER_PORT}:9487"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
pihole:
|
||||||
|
image: pihole/pihole:latest
|
||||||
|
container_name: ${HOSTNAME}-pihole
|
||||||
|
hostname: ${HOSTNAME}
|
||||||
|
ports:
|
||||||
|
- "${PIHOLE_WEB_PORT}:80"
|
||||||
|
- "${PIHOLE_HTTPS_PORT}:443"
|
||||||
|
- "${PIHOLE_DNS_PORT}:53/udp"
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
WEBPASSWORD: ${WEBPASSWORD}
|
||||||
|
volumes:
|
||||||
|
- pihole-config:/etc/pihole
|
||||||
|
- dnsmasq-config:/etc/dnsmasq.d
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
prometheus-data:
|
||||||
|
loki-data:
|
||||||
|
pihole-config:
|
||||||
|
dnsmasq-config:
|
||||||
27
pi/stack-status.sh
Executable file
27
pi/stack-status.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Optional base hostname (e.g., monitor.local)
|
||||||
|
BASE_HOST="${NGINX_HOST:-localhost}"
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
||||||
|
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
for container in $(docker ps --format '{{.Names}}'); do
|
||||||
|
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
||||||
|
|
||||||
|
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
||||||
|
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
||||||
|
|
||||||
|
if [ -z "$ports" ]; then
|
||||||
|
ports="(none)"
|
||||||
|
url="(none)"
|
||||||
|
else
|
||||||
|
# Just use the first port for URL
|
||||||
|
first_port=$(echo "$ports" | cut -d',' -f1)
|
||||||
|
scheme="http"
|
||||||
|
[ "$first_port" = "443" ] && scheme="https"
|
||||||
|
url="$scheme://$BASE_HOST:$first_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
||||||
|
done
|
||||||
16
pi/start.sh
Executable file
16
pi/start.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🚀 Starting monitoring stack..."
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Failed to start containers. Check docker-compose logs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 Gathering service info:"
|
||||||
|
./stack-status.sh
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
# 🛠️ Mystic Stack: Node Onboarding Guide
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install ca-certificates curl gnupg git -y
|
|
||||||
|
|
||||||
# Add Docker’s official GPG key
|
|
||||||
sudo install -m 0755 -d /etc/apt/keyrings
|
|
||||||
curl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
||||||
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
|
||||||
|
|
||||||
# Add the repository to Apt sources
|
|
||||||
echo \
|
|
||||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu) \
|
|
||||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
||||||
|
|
||||||
# Install Docker Stack
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
|
|
||||||
|
|
||||||
sudo usermod -aG docker $USER
|
|
||||||
newgrp docker
|
|
||||||
|
|
||||||
# Generate key (Press Enter for all prompts)
|
|
||||||
ssh-keygen -t ed25519 -C "$(hostname)"
|
|
||||||
|
|
||||||
# Output public key for Forgejo Web UI
|
|
||||||
cat ~/.ssh/id_ed25519.pub
|
|
||||||
|
|
||||||
# Setup Directory
|
|
||||||
mkdir -p ~/mystic-stack && cd ~/mystic-stack
|
|
||||||
|
|
||||||
# Clone Repository (Using Tailscale IP of Git VM)
|
|
||||||
git clone git@100.98.158.31:bray/infra.git .
|
|
||||||
|
|
||||||
# Launch Node Exporter
|
|
||||||
docker compose -f nodes/docker-compose.node.yml up -d
|
|
||||||
19
ubuntu-1/Dockerfile.alertmanager
Normal file
19
ubuntu-1/Dockerfile.alertmanager
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Stage 1: Pull original Alertmanager binary
|
||||||
|
FROM prom/alertmanager:latest as upstream
|
||||||
|
|
||||||
|
# Stage 2: Alpine + envsubst
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install envsubst and ca-certificates
|
||||||
|
RUN apk add --no-cache gettext ca-certificates
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
RUN mkdir -p /etc/alertmanager /alertmanager
|
||||||
|
|
||||||
|
# Copy Alertmanager binary from upstream
|
||||||
|
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
||||||
|
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
||||||
|
|
||||||
|
# Default config will be overwritten by volume mount
|
||||||
|
ENTRYPOINT ["/bin/sh", "-c"]
|
||||||
|
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
||||||
14
ubuntu-1/configs/alertmanager/alertmanager.template.yml
Normal file
14
ubuntu-1/configs/alertmanager/alertmanager.template.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
14
ubuntu-1/configs/alertmanager/alertmanager.yml
Normal file
14
ubuntu-1/configs/alertmanager/alertmanager.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
53
ubuntu-1/configs/loki/loki-config.yml
Normal file
53
ubuntu-1/configs/loki/loki-config.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9095
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
lifecycler:
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
chunk_idle_period: 5m
|
||||||
|
chunk_retain_period: 30s
|
||||||
|
wal:
|
||||||
|
dir: /loki/wal
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
allow_structured_metadata: false
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v12
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: /loki/index
|
||||||
|
cache_location: /loki/cache
|
||||||
|
filesystem:
|
||||||
|
directory: /loki/chunks
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: /loki/rules
|
||||||
|
rule_path: /loki/rules-temp
|
||||||
|
alertmanager_url: http://localhost:9093
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
19
ubuntu-1/configs/prometheus/prometheus.yml
Normal file
19
ubuntu-1/configs/prometheus/prometheus.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9090']
|
||||||
|
|
||||||
|
- job_name: 'node_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9100']
|
||||||
|
|
||||||
|
- job_name: 'docker_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9487']
|
||||||
|
|
||||||
|
- job_name: 'pi_services'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:3100', 'localhost:9093']
|
||||||
9
ubuntu-1/configs/promtail/positions.yaml
Normal file
9
ubuntu-1/configs/promtail/positions.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
positions:
|
||||||
|
/var/log/alf.log: "0"
|
||||||
|
/var/log/fsck_apfs.log: "23880"
|
||||||
|
/var/log/fsck_apfs_error.log: "676"
|
||||||
|
/var/log/fsck_hfs.log: "4044"
|
||||||
|
/var/log/install.log: "3800109"
|
||||||
|
/var/log/shutdown_monitor.log: "1971"
|
||||||
|
/var/log/system.log: "6132"
|
||||||
|
/var/log/wifi.log: "1107090"
|
||||||
18
ubuntu-1/configs/promtail/promtail.yml
Normal file
18
ubuntu-1/configs/promtail/promtail.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
server:
|
||||||
|
http_listen_port: 9080
|
||||||
|
grpc_listen_port: 0
|
||||||
|
|
||||||
|
positions:
|
||||||
|
filename: /etc/promtail/positions.yaml
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- url: http://loki:3100/loki/api/v1/push
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: system
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: varlogs
|
||||||
|
__path__: /var/log/*.log
|
||||||
68
ubuntu-1/docker-compose.yml
Normal file
68
ubuntu-1/docker-compose.yml
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
container_name: ${HOSTNAME}-prometheus
|
||||||
|
ports:
|
||||||
|
- "${PROMETHEUS_PORT}:9090"
|
||||||
|
volumes:
|
||||||
|
- ./configs/prometheus:/etc/prometheus
|
||||||
|
- prometheus-data:/prometheus
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
alertmanager:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.alertmanager
|
||||||
|
container_name: ${HOSTNAME}-alertmanager
|
||||||
|
ports:
|
||||||
|
- "${ALERTMANAGER_PORT}:9093"
|
||||||
|
volumes:
|
||||||
|
- ./configs/alertmanager:/etc/alertmanager
|
||||||
|
environment:
|
||||||
|
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:latest
|
||||||
|
container_name: ${HOSTNAME}-loki
|
||||||
|
ports:
|
||||||
|
- "${LOKI_PORT}:3100"
|
||||||
|
volumes:
|
||||||
|
- ./configs/loki:/etc/loki
|
||||||
|
- loki-data:/loki
|
||||||
|
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
promtail:
|
||||||
|
image: grafana/promtail:latest
|
||||||
|
container_name: ${HOSTNAME}-promtail
|
||||||
|
volumes:
|
||||||
|
- /var/log:/var/log:ro
|
||||||
|
- ./configs/promtail:/etc/promtail
|
||||||
|
command: -config.file=/etc/promtail/promtail.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
node_exporter:
|
||||||
|
image: prom/node-exporter:latest
|
||||||
|
container_name: ${HOSTNAME}-node_exporter
|
||||||
|
ports:
|
||||||
|
- "${NODE_EXPORTER_PORT}:9100"
|
||||||
|
command:
|
||||||
|
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
docker_exporter:
|
||||||
|
image: prometheusnet/docker_exporter
|
||||||
|
container_name: ${HOSTNAME}-docker_exporter
|
||||||
|
ports:
|
||||||
|
- "${DOCKER_EXPORTER_PORT}:9487"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
prometheus-data:
|
||||||
|
loki-data:
|
||||||
27
ubuntu-1/stack-status.sh
Executable file
27
ubuntu-1/stack-status.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Optional base hostname (e.g., monitor.local)
|
||||||
|
BASE_HOST="${NGINX_HOST:-localhost}"
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
||||||
|
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
for container in $(docker ps --format '{{.Names}}'); do
|
||||||
|
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
||||||
|
|
||||||
|
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
||||||
|
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
||||||
|
|
||||||
|
if [ -z "$ports" ]; then
|
||||||
|
ports="(none)"
|
||||||
|
url="(none)"
|
||||||
|
else
|
||||||
|
# Just use the first port for URL
|
||||||
|
first_port=$(echo "$ports" | cut -d',' -f1)
|
||||||
|
scheme="http"
|
||||||
|
[ "$first_port" = "443" ] && scheme="https"
|
||||||
|
url="$scheme://$BASE_HOST:$first_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
||||||
|
done
|
||||||
16
ubuntu-1/start.sh
Executable file
16
ubuntu-1/start.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🚀 Starting monitoring stack..."
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Failed to start containers. Check docker-compose logs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 Gathering service info:"
|
||||||
|
./stack-status.sh
|
||||||
19
ubuntu-2/Dockerfile.alertmanager
Normal file
19
ubuntu-2/Dockerfile.alertmanager
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Stage 1: Pull original Alertmanager binary
|
||||||
|
FROM prom/alertmanager:latest as upstream
|
||||||
|
|
||||||
|
# Stage 2: Alpine + envsubst
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install envsubst and ca-certificates
|
||||||
|
RUN apk add --no-cache gettext ca-certificates
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
RUN mkdir -p /etc/alertmanager /alertmanager
|
||||||
|
|
||||||
|
# Copy Alertmanager binary from upstream
|
||||||
|
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
||||||
|
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
||||||
|
|
||||||
|
# Default config will be overwritten by volume mount
|
||||||
|
ENTRYPOINT ["/bin/sh", "-c"]
|
||||||
|
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
||||||
14
ubuntu-2/configs/alertmanager/alertmanager.template.yml
Normal file
14
ubuntu-2/configs/alertmanager/alertmanager.template.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
14
ubuntu-2/configs/alertmanager/alertmanager.yml
Normal file
14
ubuntu-2/configs/alertmanager/alertmanager.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
53
ubuntu-2/configs/loki/loki-config.yml
Normal file
53
ubuntu-2/configs/loki/loki-config.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9095
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
lifecycler:
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
chunk_idle_period: 5m
|
||||||
|
chunk_retain_period: 30s
|
||||||
|
wal:
|
||||||
|
dir: /loki/wal
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
allow_structured_metadata: false
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v12
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: /loki/index
|
||||||
|
cache_location: /loki/cache
|
||||||
|
filesystem:
|
||||||
|
directory: /loki/chunks
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: /loki/rules
|
||||||
|
rule_path: /loki/rules-temp
|
||||||
|
alertmanager_url: http://localhost:9093
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
19
ubuntu-2/configs/prometheus/prometheus.yml
Normal file
19
ubuntu-2/configs/prometheus/prometheus.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9090']
|
||||||
|
|
||||||
|
- job_name: 'node_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9100']
|
||||||
|
|
||||||
|
- job_name: 'docker_exporter'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9487']
|
||||||
|
|
||||||
|
- job_name: 'pi_services'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:3100', 'localhost:9093']
|
||||||
9
ubuntu-2/configs/promtail/positions.yaml
Normal file
9
ubuntu-2/configs/promtail/positions.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
positions:
|
||||||
|
/var/log/alf.log: "0"
|
||||||
|
/var/log/fsck_apfs.log: "23880"
|
||||||
|
/var/log/fsck_apfs_error.log: "676"
|
||||||
|
/var/log/fsck_hfs.log: "4044"
|
||||||
|
/var/log/install.log: "3800109"
|
||||||
|
/var/log/shutdown_monitor.log: "1971"
|
||||||
|
/var/log/system.log: "6069"
|
||||||
|
/var/log/wifi.log: "1107090"
|
||||||
18
ubuntu-2/configs/promtail/promtail.yml
Normal file
18
ubuntu-2/configs/promtail/promtail.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
server:
|
||||||
|
http_listen_port: 9080
|
||||||
|
grpc_listen_port: 0
|
||||||
|
|
||||||
|
positions:
|
||||||
|
filename: /etc/promtail/positions.yaml
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- url: http://loki:3100/loki/api/v1/push
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: system
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: varlogs
|
||||||
|
__path__: /var/log/*.log
|
||||||
68
ubuntu-2/docker-compose.yml
Normal file
68
ubuntu-2/docker-compose.yml
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
container_name: ${HOSTNAME}-prometheus
|
||||||
|
ports:
|
||||||
|
- "${PROMETHEUS_PORT}:9090"
|
||||||
|
volumes:
|
||||||
|
- ./configs/prometheus:/etc/prometheus
|
||||||
|
- prometheus-data:/prometheus
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
alertmanager:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.alertmanager
|
||||||
|
container_name: ${HOSTNAME}-alertmanager
|
||||||
|
ports:
|
||||||
|
- "${ALERTMANAGER_PORT}:9093"
|
||||||
|
volumes:
|
||||||
|
- ./configs/alertmanager:/etc/alertmanager
|
||||||
|
environment:
|
||||||
|
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:latest
|
||||||
|
container_name: ${HOSTNAME}-loki
|
||||||
|
ports:
|
||||||
|
- "${LOKI_PORT}:3100"
|
||||||
|
volumes:
|
||||||
|
- ./configs/loki:/etc/loki
|
||||||
|
- loki-data:/loki
|
||||||
|
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
promtail:
|
||||||
|
image: grafana/promtail:latest
|
||||||
|
container_name: ${HOSTNAME}-promtail
|
||||||
|
volumes:
|
||||||
|
- /var/log:/var/log:ro
|
||||||
|
- ./configs/promtail:/etc/promtail
|
||||||
|
command: -config.file=/etc/promtail/promtail.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
node_exporter:
|
||||||
|
image: prom/node-exporter:latest
|
||||||
|
container_name: ${HOSTNAME}-node_exporter
|
||||||
|
ports:
|
||||||
|
- "${NODE_EXPORTER_PORT}:9100"
|
||||||
|
command:
|
||||||
|
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
docker_exporter:
|
||||||
|
image: prometheusnet/docker_exporter
|
||||||
|
container_name: ${HOSTNAME}-docker_exporter
|
||||||
|
ports:
|
||||||
|
- "${DOCKER_EXPORTER_PORT}:9487"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
prometheus-data:
|
||||||
|
loki-data:
|
||||||
27
ubuntu-2/stack-status.sh
Executable file
27
ubuntu-2/stack-status.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Optional base hostname (e.g., monitor.local)
|
||||||
|
BASE_HOST="${NGINX_HOST:-localhost}"
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
||||||
|
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
for container in $(docker ps --format '{{.Names}}'); do
|
||||||
|
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
||||||
|
|
||||||
|
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
||||||
|
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
||||||
|
|
||||||
|
if [ -z "$ports" ]; then
|
||||||
|
ports="(none)"
|
||||||
|
url="(none)"
|
||||||
|
else
|
||||||
|
# Just use the first port for URL
|
||||||
|
first_port=$(echo "$ports" | cut -d',' -f1)
|
||||||
|
scheme="http"
|
||||||
|
[ "$first_port" = "443" ] && scheme="https"
|
||||||
|
url="$scheme://$BASE_HOST:$first_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
||||||
|
done
|
||||||
16
ubuntu-2/start.sh
Executable file
16
ubuntu-2/start.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🚀 Starting monitoring stack..."
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Failed to start containers. Check docker-compose logs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 Gathering service info:"
|
||||||
|
./stack-status.sh
|
||||||
19
unraid/Dockerfile.alertmanager
Normal file
19
unraid/Dockerfile.alertmanager
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Stage 1: Pull original Alertmanager binary
|
||||||
|
FROM prom/alertmanager:latest as upstream
|
||||||
|
|
||||||
|
# Stage 2: Alpine + envsubst
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install envsubst and ca-certificates
|
||||||
|
RUN apk add --no-cache gettext ca-certificates
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
RUN mkdir -p /etc/alertmanager /alertmanager
|
||||||
|
|
||||||
|
# Copy Alertmanager binary from upstream
|
||||||
|
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
||||||
|
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
||||||
|
|
||||||
|
# Default config will be overwritten by volume mount
|
||||||
|
ENTRYPOINT ["/bin/sh", "-c"]
|
||||||
|
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
||||||
14
unraid/configs/alertmanager/alertmanager.template.yml
Normal file
14
unraid/configs/alertmanager/alertmanager.template.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: '${DISCORD_ALERT_WEBHOOK}'
|
||||||
|
send_resolved: true
|
||||||
14
unraid/configs/alertmanager/alertmanager.yml
Normal file
14
unraid/configs/alertmanager/alertmanager.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
global:
|
||||||
|
resolve_timeout: 5m
|
||||||
|
|
||||||
|
route:
|
||||||
|
receiver: 'discord'
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 30s
|
||||||
|
repeat_interval: 1h
|
||||||
|
|
||||||
|
receivers:
|
||||||
|
- name: 'discord'
|
||||||
|
webhook_configs:
|
||||||
|
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
||||||
|
send_resolved: true
|
||||||
0
unraid/configs/grafana/grafana.ini
Normal file
0
unraid/configs/grafana/grafana.ini
Normal file
53
unraid/configs/loki/loki-config.yml
Normal file
53
unraid/configs/loki/loki-config.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9095
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
lifecycler:
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
replication_factor: 1
|
||||||
|
chunk_idle_period: 5m
|
||||||
|
chunk_retain_period: 30s
|
||||||
|
wal:
|
||||||
|
dir: /loki/wal
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
allow_structured_metadata: false
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: boltdb-shipper
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v12
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
boltdb_shipper:
|
||||||
|
active_index_directory: /loki/index
|
||||||
|
cache_location: /loki/cache
|
||||||
|
filesystem:
|
||||||
|
directory: /loki/chunks
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: /loki/rules
|
||||||
|
rule_path: /loki/rules-temp
|
||||||
|
alertmanager_url: http://localhost:9093
|
||||||
|
ring:
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
enable_api: true
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
0
unraid/configs/nginx/default.conf
Normal file
0
unraid/configs/nginx/default.conf
Normal file
0
unraid/configs/prometheus/prometheus.yml
Normal file
0
unraid/configs/prometheus/prometheus.yml
Normal file
18
unraid/configs/promtail/promtail.yml
Normal file
18
unraid/configs/promtail/promtail.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
server:
|
||||||
|
http_listen_port: 9080
|
||||||
|
grpc_listen_port: 0
|
||||||
|
|
||||||
|
positions:
|
||||||
|
filename: /tmp/positions.yaml
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- url: http://loki:3100/loki/api/v1/push
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: system
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: varlogs
|
||||||
|
__path__: /var/log/*.log
|
||||||
94
unraid/docker-compose.yml
Normal file
94
unraid/docker-compose.yml
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
alertmanager:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.alertmanager
|
||||||
|
container_name: ${HOSTNAME}-alertmanager
|
||||||
|
ports:
|
||||||
|
- "9093:9093"
|
||||||
|
volumes:
|
||||||
|
- ./configs/alertmanager:/etc/alertmanager
|
||||||
|
environment:
|
||||||
|
- DISCORD_ALERT_WEBHOOK=${DISCORD_ALERT_WEBHOOK}
|
||||||
|
restart: unless-stopped
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
container_name: ${HOSTNAME}-grafana
|
||||||
|
ports:
|
||||||
|
- "${GRAFANA_PORT}:3000"
|
||||||
|
environment:
|
||||||
|
- GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
|
||||||
|
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASS}
|
||||||
|
volumes:
|
||||||
|
- ./configs/grafana:/etc/grafana
|
||||||
|
- grafana-data:/var/lib/grafana
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
container_name: ${HOSTNAME}-prometheus
|
||||||
|
ports:
|
||||||
|
- "${PROMETHEUS_PORT}:9090"
|
||||||
|
volumes:
|
||||||
|
- ./configs/prometheus:/etc/prometheus
|
||||||
|
- prometheus-data:/prometheus
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:latest
|
||||||
|
container_name: ${HOSTNAME}-loki
|
||||||
|
ports:
|
||||||
|
- "${LOKI_PORT}:3100"
|
||||||
|
volumes:
|
||||||
|
- ./configs/loki:/etc/loki
|
||||||
|
- loki-data:/loki
|
||||||
|
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
promtail:
|
||||||
|
image: grafana/promtail:latest
|
||||||
|
container_name: ${HOSTNAME}-promtail
|
||||||
|
volumes:
|
||||||
|
- /var/log:/var/log:ro
|
||||||
|
- ./configs/promtail:/etc/promtail
|
||||||
|
command: -config.file=/etc/promtail/promtail.yml
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
docker_exporter:
|
||||||
|
image: prometheusnet/docker_exporter
|
||||||
|
container_name: ${HOSTNAME}-docker_exporter
|
||||||
|
ports:
|
||||||
|
- "${DOCKER_EXPORTER_PORT}:9487"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
node_exporter:
|
||||||
|
image: prom/node-exporter:latest
|
||||||
|
container_name: ${HOSTNAME}-node_exporter
|
||||||
|
ports:
|
||||||
|
- "${NODE_EXPORTER_PORT}:9100"
|
||||||
|
command:
|
||||||
|
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:latest
|
||||||
|
container_name: ${HOSTNAME}-nginx
|
||||||
|
ports:
|
||||||
|
- "${NGINX_HTTP_PORT}:80"
|
||||||
|
- "${NGINX_HTTPS_PORT}:443"
|
||||||
|
volumes:
|
||||||
|
- ./configs/nginx:/etc/nginx/conf.d
|
||||||
|
- ./configs/nginx/ssl:/etc/nginx/ssl
|
||||||
|
- ./configs/nginx/html:/usr/share/nginx/html
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
grafana-data:
|
||||||
|
prometheus-data:
|
||||||
|
loki-data:
|
||||||
27
unraid/stack-status.sh
Executable file
27
unraid/stack-status.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Optional base hostname (e.g., monitor.local)
|
||||||
|
BASE_HOST="${NGINX_HOST:-localhost}"
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
||||||
|
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
for container in $(docker ps --format '{{.Names}}'); do
|
||||||
|
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
||||||
|
|
||||||
|
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
||||||
|
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
||||||
|
|
||||||
|
if [ -z "$ports" ]; then
|
||||||
|
ports="(none)"
|
||||||
|
url="(none)"
|
||||||
|
else
|
||||||
|
# Just use the first port for URL
|
||||||
|
first_port=$(echo "$ports" | cut -d',' -f1)
|
||||||
|
scheme="http"
|
||||||
|
[ "$first_port" = "443" ] && scheme="https"
|
||||||
|
url="$scheme://$BASE_HOST:$first_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
||||||
|
done
|
||||||
16
unraid/start.sh
Executable file
16
unraid/start.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🚀 Starting monitoring stack..."
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Failed to start containers. Check docker-compose logs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 Gathering service info:"
|
||||||
|
./stack-status.sh
|
||||||
Loading…
Reference in a new issue