# ============================================ # RomM Automation — TrueNAS Promotion Compose # ============================================ # Target: TrueNAS regular Docker / Portainer Compose deployment. # Purpose: run the request/intake helpers near the production RomM library. # # Source of truth: # gitea@192.168.20.254:Wheelz/Docker-Compose-Stacks.git # # Deploy after creating a real runtime env file on TrueNAS/Portainer: # docker compose --env-file romm-automation.env -f romm-automation-truenas-compose.yml up -d # # Validate with example values: # docker compose --env-file romm-automation-truenas.env.example -f romm-automation-truenas-compose.yml config # # Notes: # - Keep secrets out of Git. Real .env files are ignored by .gitignore. # - Keep this LAN/VPN-only until auth/reverse-proxy behavior is reviewed. # - Romarr is still experimental here; upstream image availability must be confirmed. # - Staging stays separate from the production RomM library. # - Igir mounts the production RomM library only for the validation/import profile. # ============================================ name: romm-automation services: ggrequestz: image: ghcr.io/xtreemmak/ggrequestz:latest container_name: ggrequestz restart: unless-stopped depends_on: ggrequestz-postgres: condition: service_healthy ggrequestz-redis: condition: service_healthy ggrequestz-typesense: condition: service_started ports: - "${GGREQUESTZ_PORT:-3003}:3000" environment: PUID: ${PUID:-568} PGID: ${PGID:-568} TZ: ${TZ:-America/Chicago} NODE_ENV: production APP_PORT: 3000 PUBLIC_SITE_URL: ${GGREQUESTZ_PUBLIC_SITE_URL:-http://localhost:3003} POSTGRES_HOST: ggrequestz-postgres POSTGRES_PORT: 5432 POSTGRES_DB: ${GGREQUESTZ_POSTGRES_DB:-ggrequestz} POSTGRES_USER: ${GGREQUESTZ_POSTGRES_USER:-ggrequestz} POSTGRES_PASSWORD: ${GGREQUESTZ_POSTGRES_PASSWORD:?set GGREQUESTZ_POSTGRES_PASSWORD in .env} REDIS_URL: redis://:${GGREQUESTZ_REDIS_PASSWORD:?set GGREQUESTZ_REDIS_PASSWORD in .env}@ggrequestz-redis:6379 TYPESENSE_HOST: ggrequestz-typesense TYPESENSE_PORT: 8108 TYPESENSE_PROTOCOL: http TYPESENSE_API_KEY: ${GGREQUESTZ_TYPESENSE_API_KEY:?set GGREQUESTZ_TYPESENSE_API_KEY in .env} AUTH_METHOD: ${GGREQUESTZ_AUTH_METHOD:-basic} AUTHENTIK_CLIENT_ID: ${GGREQUESTZ_AUTHENTIK_CLIENT_ID:-} AUTHENTIK_CLIENT_SECRET: ${GGREQUESTZ_AUTHENTIK_CLIENT_SECRET:-} AUTHENTIK_ISSUER: ${GGREQUESTZ_AUTHENTIK_ISSUER:-} SESSION_SECRET: ${GGREQUESTZ_SESSION_SECRET:?set GGREQUESTZ_SESSION_SECRET in .env} IGDB_CLIENT_ID: ${IGDB_CLIENT_ID:?set IGDB_CLIENT_ID in .env} IGDB_CLIENT_SECRET: ${IGDB_CLIENT_SECRET:?set IGDB_CLIENT_SECRET in .env} ROMM_SERVER_URL: ${ROMM_SERVER_URL:-} ROMM_USERNAME: ${ROMM_USERNAME:-} ROMM_PASSWORD: ${ROMM_PASSWORD:-} volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/ggrequestz/app:/app/data networks: - romm-automation ggrequestz-postgres: image: postgres:16-alpine container_name: ggrequestz-postgres restart: unless-stopped # postgres:16-alpine uses UID/GID 70 internally after init. On TrueNAS, make sure # this dataset path can be written by the container during first startup. environment: POSTGRES_DB: ${GGREQUESTZ_POSTGRES_DB:-ggrequestz} POSTGRES_USER: ${GGREQUESTZ_POSTGRES_USER:-ggrequestz} POSTGRES_PASSWORD: ${GGREQUESTZ_POSTGRES_PASSWORD:?set GGREQUESTZ_POSTGRES_PASSWORD in .env} TZ: ${TZ:-America/Chicago} PGDATA: /var/lib/postgresql/data/pgdata volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/ggrequestz/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${GGREQUESTZ_POSTGRES_USER:-ggrequestz} -d ${GGREQUESTZ_POSTGRES_DB:-ggrequestz}"] interval: 30s timeout: 5s retries: 5 start_period: 30s networks: - romm-automation ggrequestz-redis: image: redis:7-alpine container_name: ggrequestz-redis restart: unless-stopped command: ["redis-server", "--appendonly", "yes", "--requirepass", "${GGREQUESTZ_REDIS_PASSWORD:?set GGREQUESTZ_REDIS_PASSWORD in .env}"] volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/ggrequestz/redis:/data healthcheck: test: ["CMD", "redis-cli", "-a", "${GGREQUESTZ_REDIS_PASSWORD:?set GGREQUESTZ_REDIS_PASSWORD in .env}", "ping"] interval: 30s timeout: 5s retries: 5 start_period: 10s networks: - romm-automation ggrequestz-typesense: image: typesense/typesense:27.1 container_name: ggrequestz-typesense restart: unless-stopped command: ["--data-dir", "/data", "--api-key", "${GGREQUESTZ_TYPESENSE_API_KEY:?set GGREQUESTZ_TYPESENSE_API_KEY in .env}", "--enable-cors"] volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/ggrequestz/typesense:/data # Typesense's official image does not consistently include wget/curl, so avoid # a container-internal HTTP healthcheck here. GG Requestz can still retry while # Typesense finishes startup. networks: - romm-automation romarr: image: ${ROMARR_IMAGE:-romarr/romarr:latest} container_name: romarr restart: unless-stopped profiles: ["romarr"] ports: - "${ROMARR_PORT:-9797}:9797" environment: PUID: ${PUID:-568} PGID: ${PGID:-568} TZ: ${TZ:-America/Chicago} volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/romarr/config:/config - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/staging/romarr-library:/roms - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/staging/downloads:/downloads networks: - romm-automation romm-comm: image: idiosync000/romm-comm:latest container_name: romm-comm restart: unless-stopped profiles: ["discord"] environment: TZ: ${TZ:-America/Chicago} TOKEN: ${ROMMCOMM_DISCORD_TOKEN:?set ROMMCOMM_DISCORD_TOKEN in .env} GUILD: ${ROMMCOMM_GUILD_ID:?set ROMMCOMM_GUILD_ID in .env} API_URL: ${ROMM_SERVER_URL:?set ROMM_SERVER_URL in .env} USER: ${ROMM_USERNAME:?set ROMM_USERNAME in .env} PASS: ${ROMM_PASSWORD:?set ROMM_PASSWORD in .env} ADMIN_ID: ${ROMMCOMM_ADMIN_ID:-} DOMAIN: ${ROMMCOMM_DOMAIN:-} REQUESTS_ENABLED: ${ROMMCOMM_REQUESTS_ENABLED:-true} IGDB_CLIENT_ID: ${IGDB_CLIENT_ID:-} IGDB_CLIENT_SECRET: ${IGDB_CLIENT_SECRET:-} CHANNEL_ID: ${ROMMCOMM_CHANNEL_ID:-} RECENT_ROMS_ENABLED: ${ROMMCOMM_RECENT_ROMS_ENABLED:-true} RECENT_ROMS_CHANNEL_ID: ${ROMMCOMM_RECENT_ROMS_CHANNEL_ID:-} GGREQUESTZ_ENABLED: ${ROMMCOMM_GGREQUESTZ_ENABLED:-true} GGREQUESTZ_URL: http://ggrequestz:3000 GGREQUESTZ_API_KEY: ${GGREQUESTZ_API_KEY:-} volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/romm-comm/data:/app/data networks: - romm-automation igir-worker: image: node:22-alpine container_name: igir-worker restart: unless-stopped profiles: ["validation"] working_dir: /work command: ["sh", "-c", "apk add --no-cache python3 make g++ && npm install -g igir@latest && sleep infinity"] volumes: - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/staging:/staging - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/dat:/dat:ro - ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/RomAutomation/reports:/reports - ${ROMM_LIBRARY_PATH:?set ROMM_LIBRARY_PATH in .env}:/romm/library networks: - romm-automation networks: romm-automation: name: romm-automation driver: bridge