Files
CC-Manager/compose.yaml
T
Harlekin 664a0fd5ee Forums-Anträge erfassen und von Hand entscheiden
Der GExtension-Abgleich liefert die Käufe, der Verbrauch steht im Forum. Die
App liest jetzt die drei CC-Boards und sammelt die Anträge.

Gelesen wird nur die Board-Übersicht: sie führt bereits den Ersteller, nicht
nur den letzten Antwortenden. Damit bleibt ein Lauf bei wenigen Anfragen statt
einer je Thread. Unterforen und globale Kästen tragen ebenfalls Thread-Links,
deshalb liest der Parser strikt entlang der Listeneinträge - sonst landen
Changelogs und Bewerbungen in der Antragsliste.

Klassifiziert wird ausschließlich von Hand. Weder Titel noch Board sind
verlässlich genug: Threads werden nicht immer verschoben, ein genehmigter
Antrag kann weiter im Antrags-Board liegen. Das Board steht deshalb nur als
Hinweis an der Zeile.

Angenommene Anträge rufen dieselben Aktionen wie die Knöpfe auf der
Spielerseite, es gibt keinen zweiten Buchungsweg mit eigenen Regeln. Wandert
ein bereits entschiedener Thread später in ein anderes Board, erscheint das
als Hinweis zum Abhaken - der CC-Status ändert sich nie von allein.

Die Thread-ID bleibt beim Verschieben stabil und traegt deshalb die
Wiedererkennung; die Board-Historie wird mitgeschrieben. Zurückgelassene
Verweise erkennt der Parser und zählt sie nicht als eigenen Antrag.
2026-09-18 17:32:58 +02:00

77 lines
2.5 KiB
YAML

services:
app:
build: .
# Alternativ ein vorgebautes Image verwenden:
# image: ghcr.io/harlekin/cc-manager:latest
restart: unless-stopped
environment:
DATABASE_URL: postgres://ccuser:${DB_PASSWORD}@db:5432/ccmanager
SESSION_SECRET: ${SESSION_SECRET}
NODE_ENV: production
# Erstzugang; nach der ersten Anmeldung wird ein Wechsel erzwungen.
BOOTSTRAP_ADMIN_USER: ${BOOTSTRAP_ADMIN_USER:-admin}
BOOTSTRAP_ADMIN_PASSWORD: ${BOOTSTRAP_ADMIN_PASSWORD:-}
TRUST_PROXY: "true"
# Nur nötig, wenn der GExtension-Abgleich eine andere Instanz ansprechen soll.
GEXTENSION_BASE_URL: ${GEXTENSION_BASE_URL:-https://gextension.senseigaming.de}
FORUM_BASE_URL: ${FORUM_BASE_URL:-https://senseigaming.de/forum}
AUDIT_RETENTION_DAYS: ${AUDIT_RETENTION_DAYS:-365}
expose:
# Bewusst nicht nach aussen gemappt: der Reverse Proxy terminiert HTTPS.
- "3000"
depends_on:
db:
condition: service_healthy
networks:
- default # App zur Datenbank
- proxy # Reverse Proxy zur App
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ccuser
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ccmanager
volumes:
- cc_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ccuser -d ccmanager"]
interval: 10s
timeout: 5s
retries: 5
backup:
image: postgres:16-alpine
restart: unless-stopped
environment:
PGPASSWORD: ${DB_PASSWORD}
volumes:
- ./backups:/backups
depends_on:
db:
condition: service_healthy
# Dump beim Start und danach alle 24 Stunden, Aufbewahrung 14 Tage.
entrypoint: >
sh -c 'while true; do
pg_dump -h db -U ccuser -d ccmanager | gzip > /backups/ccmanager-$$(date +%F-%H%M).sql.gz &&
echo "Backup geschrieben: $$(date +%F-%H%M)";
find /backups -name "ccmanager-*.sql.gz" -mtime +14 -delete;
sleep 86400;
done'
networks:
# Das Netzwerk des Reverse Proxy. Es muss bereits existieren - der Proxy
# legt es an, bei Nginx Proxy Manager heisst es meist nginx_default.
# Anderer Name? Dann PROXY_NETWORK in der .env setzen.
#
# Ohne Reverse Proxy in Docker: diesen Block und die networks-Liste beim
# app-Service entfernen und stattdessen einen Port mappen (ports: "3000:3000").
# Dann aber selbst für HTTPS sorgen - die App gehört nicht ungeschuetzt ins Netz.
proxy:
external: true
name: ${PROXY_NETWORK:-nginx_default}
volumes:
cc_db: