Files
serverAppConfigs/dankserver/compose.yaml
T
Frank da9cff046e observability: give Dankserver its node-exporter back as a Quadlet
Dankserver's node-exporter has been dead since a reboot: `podman ps -a` showed
it `Exited (143)` and Prometheus' `node-dankserver` job has been scraping
nothing. It ran only from `dankserver/compose.yaml`, which is the failure mode
this repository's boot-persistence rule exists for (rootless Podman does not
restart bare containers after the stop that shutdown performs), and the compose
form bound the wildcard address — the unauthenticated-metrics-API-on-every-
interface posture already removed on Dankclaw.

  - dankserver/observability/quadlet/node-exporter.container — mirrors the
    Dankclaw unit, listening on exactly 127.0.0.1:9100 (host-local probes) and
    192.168.0.235:9100 (Prometheus on Dankclaw), with Restart=always and
    WantedBy=default.target.
  - the compose service is deleted: one owner per container name.
  - deploy_observability now installs from "$TARGET/observability/quadlet"; it
    hardcoded the Dankclaw path, so a Dankserver unit could not be installed by
    the shared dispatcher at all.
  - planner: "node-exporter" joins the Dankserver service set, with a path rule
    for dankserver/observability/**; the dispatcher's allowlist gains
    dankserver:node-exporter.

Seams cover the silent halves: both listen addresses present and the wildcard
absent, the compose service gone, the allowlist entry present, and the planner
mapping the path to the service.
2026-09-16 07:07:18 -07:00

155 lines
5.5 KiB
YAML

# Dankserver stack — media & library services.
# Deploy: cd /home/dank/serverAppConfigs && podman-compose -f dankserver/compose.yaml up -d
# See ../docs/Dankserver/ for service documentation.
networks:
appnet:
driver: bridge
services:
# ═══════════════════════════════════════════════
# RomM — retro game manager (requires MariaDB + Redis)
# ═══════════════════════════════════════════════
mariadb:
image: docker.io/mariadb:11
container_name: romm-mariadb
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}"
MARIADB_DATABASE: romm
MARIADB_USER: "${ROMM_DB_USER}"
MARIADB_PASSWORD: "${ROMM_DB_PASSWD}"
volumes:
- /opt/romm/mariadb:/var/lib/mysql
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 3
redis:
image: docker.io/redis:7-alpine
container_name: romm-redis
restart: unless-stopped
volumes:
- /opt/romm/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
romm:
image: ghcr.io/rommapp/romm:latest
container_name: romm
restart: unless-stopped
environment:
ROMM_USERNAME: "${ROMM_USERNAME}"
ROMM_PASSWORD: "${ROMM_PASSWORD}"
ROMM_AUTH_SECRET_KEY: "${ROMM_AUTH_SECRET_KEY}"
DB_HOST: mariadb
DB_NAME: romm
DB_USER: "${ROMM_DB_USER}"
DB_PASSWD: "${ROMM_DB_PASSWD}"
REDIS_HOST: redis
HASHEOUS_API_ENABLED: "true"
ports:
- "8085:8080"
volumes:
- /opt/romm/library:/romm/library
- /opt/romm/resources:/romm/resources
- /opt/romm/config:/romm/config
depends_on:
mariadb:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
# ═══════════════════════════════════════════════
# Copyparty — file sharing and streaming
# ═══════════════════════════════════════════════
copyparty:
image: ghcr.io/9001/copyparty-ac:latest
container_name: copyparty
restart: unless-stopped
# read-only since 2026-08-31: copyparty perms are per-field "letters[,user]"
# with no user = every unauthenticated request. Anonymous gets r (browse +
# download; the guarded files.franksdank.cloud chain reaches copyparty
# unauthenticated after authentik). dank gets ra (admin panel). No w/m/d
# anywhere: uploads, moves, deletes rejected server-side. Interface: `--help-accounts` in-image.
command: ["-a", "dank:${COPAY_PASS}", "-v", "/w::r:ra,dank"]
ports:
- "3923:3923"
volumes:
- /mnt/entropy:/w:ro
- /opt/copyparty/cfg:/cfg
healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3923/')"]
interval: 30s
timeout: 10s
retries: 3
# ═══════════════════════════════════════════════
# Jellyfin — media server (movies, TV, music)
# ═══════════════════════════════════════════════
jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
restart: unless-stopped
ports:
- "8096:8096/tcp"
- "8920:8920/tcp"
- "7359:7359/udp"
- "1900:1900/udp"
environment:
- JELLYFIN_PublishedServerUrl=http://192.168.0.235:8096
- DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true
volumes:
- /opt/jellyfin/config:/config
- /opt/jellyfin/cache:/cache
- /mnt/entropy:/data:ro
devices:
- /dev/dri:/dev/dri
group_add:
- "992"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096/health"]
interval: 30s
timeout: 10s
retries: 3
# ═══════════════════════════════════════════════
# Calibre-Web — e-book web frontend
# ═══════════════════════════════════════════════
calibre-web:
image: lscr.io/linuxserver/calibre-web:0.6.27-ls397
container_name: calibre-web
restart: unless-stopped
environment:
PUID: "1000"
PGID: "1000"
TZ: Etc/UTC
OAUTHLIB_RELAX_TOKEN_SCOPE: "1"
ports:
- "8083:8083"
volumes:
- /opt/calibre-web/config:/config
- /opt/calibre-web/books:/books
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8083/"]
interval: 30s
timeout: 10s
retries: 3
# node-exporter left this file on 2026-09-16 for
# dankserver/observability/quadlet/node-exporter.container: a compose-only
# container does not survive a reboot here — it died `Exited (143)` and stayed
# dead, leaving Prometheus' node-dankserver job scraping nothing — and the
# compose form bound the wildcard address. One owner per container name.