# GerbilManager — TrueNAS SCALE Custom App (Goldeye 25.10) # ========================================================= # Diese Datei ist die VORLAGE fuer die TrueNAS-"Custom App" (taucht unter Apps auf). # Sie wird NICHT direkt mit `docker compose` gestartet, sondern von # deploy/truenas/scripts/truenas-deploy.sh # gerendert (Platzhalter aus deploy/truenas/.env eingesetzt) und via # midclt call app.create {custom_app:true, app_name:gerbilmanager, custom_compose_config_string:} # an die TrueNAS-Middleware uebergeben. Redeploys laufen ueber `midclt call app.redeploy`. # # Unterschiede zur lokalen deploy/truenas/compose.yaml: # * ABSOLUTE Host-Bind-Pfade (Custom Apps kennen keine relativen ./-Mounts) — # gleiche Konvention wie die anderen Apps dieser NAS (/mnt/JailStorage/DockerVolumes/...). # * pull_policy: always -> `app.redeploy` zieht das frische :latest aus der Registry. # * kein publicsite-Container (oeffentliche Seite ist ein separater Schritt mit Domain/Proxy). # # Platzhalter (werden von truenas-deploy.sh aus .env ersetzt): # __POSTGRES_PASSWORD__ __REGISTRY__ __TAG__ __PORT__ __AI_BASEURL__ __AI_APIKEY__ __AI_MODEL__ services: # --- PostgreSQL 18 (Debian-Image: Locale en_US.utf8 == Quell-DB) --- db: image: postgres:18 restart: unless-stopped environment: POSTGRES_PASSWORD: "__POSTGRES_PASSWORD__" POSTGRES_DB: gerbilmanager POSTGRES_USER: postgres TZ: Europe/Berlin volumes: # postgres:18 legt PGDATA unter /var/lib/postgresql/18/docker ab und deklariert # das Volume als /var/lib/postgresql (NICHT .../data). Mount an .../data -> Start # scheitert ("data in unused mount/volume") -> db unhealthy. - /mnt/JailStorage/DockerVolumes/gerbilmanager/pgdata:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d gerbilmanager"] interval: 10s timeout: 5s retries: 5 start_period: 30s # --- .NET API --- api: image: "__REGISTRY__/gerbilmanager-api:__TAG__" pull_policy: always restart: unless-stopped environment: ASPNETCORE_ENVIRONMENT: Production ConnectionStrings__gerbilmanager: "Host=db;Port=5432;Database=gerbilmanager;Username=postgres;Password=__POSTGRES_PASSWORD__" Photos__RootPath: /data/photos DataProtection__KeyRingPath: /data/keys PublicSite__RootPath: /data/publicsite AI__BaseUrl: "__AI_BASEURL__" AI__ApiKey: "__AI_APIKEY__" AI__Model: "__AI_MODEL__" TZ: Europe/Berlin volumes: - /mnt/JailStorage/DockerVolumes/gerbilmanager/photos:/data/photos - /mnt/JailStorage/DockerVolumes/gerbilmanager/keys:/data/keys - /mnt/JailStorage/DockerVolumes/gerbilmanager/publicsite:/data/publicsite depends_on: db: condition: service_healthy healthcheck: test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 90s # --- Frontend (nginx: React-SPA + /api-Proxy) --- frontend: image: "__REGISTRY__/gerbilmanager-frontend:__TAG__" pull_policy: always restart: unless-stopped ports: - "__PORT__:80" depends_on: api: condition: service_healthy # --- Backup-Sidecar (taeglicher pg_dump + Foto-Archiv + Rotation) --- backup: image: postgres:18 restart: unless-stopped environment: PGPASSWORD: "__POSTGRES_PASSWORD__" POSTGRES_HOST: db POSTGRES_USER: postgres POSTGRES_DB: gerbilmanager BACKUP_KEEP_DAYS: "7" TZ: Europe/Berlin volumes: - /mnt/JailStorage/DockerVolumes/gerbilmanager/photos:/data/photos:ro - /mnt/JailStorage/DockerVolumes/gerbilmanager/backups:/backups - /mnt/JailStorage/DockerVolumes/gerbilmanager/scripts:/scripts:ro depends_on: db: condition: service_healthy entrypoint: ["/bin/sh", "/scripts/entrypoint.sh"]