The container has had one owner since the Quadlet cutover (dankserver/jellyfin/quadlet/jellyfin.container). The block was a second owner, and wrong on every path: jellyfin/jellyfin:latest instead of the pinned ghcr image, /opt/jellyfin/* data roots that no longer exist, and a read-only /mnt/entropy:/data bind that the metadata view has since replaced. The planner no longer counts jellyfin as a compose service, so editing the inventory cannot restart a media server; tests/deployment_scoping.bats pins that contract for both jellyfin and plex.
133 lines
5.0 KiB
YAML
133 lines
5.0 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 left this file when it became a Quadlet: the container is owned by
|
|
# dankserver/jellyfin/quadlet/jellyfin.container, its data roots are under
|
|
# /home/dank/Containers/jellyfin, and its library arrives through the SSD
|
|
# overlay at /var/lib/media-meta/view (scripts/media-view.sh). The block that
|
|
# was here named /opt/jellyfin/* and a read-only array bind — a second owner for
|
|
# the container name `jellyfin`, wrong on every path. One owner per container.
|
|
|
|
# ═══════════════════════════════════════════════
|
|
# Calibre-Web — e-book web frontend
|
|
# ═══════════════════════════════════════════════
|
|
calibre-web:
|
|
image: lscr.io/linuxserver/calibre-web:0.6.27-ls402
|
|
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.
|