# Compose OVERRIDE that adds the Go services alongside the live Python stack. # It only ADDS containers; it never modifies the tracked docker-compose.yml or # any running Python service. # # Invoke from the repo root so the Compose project name resolves to # "mosswartoverlord" (same as the live stack) and the new container joins the # existing default network — letting it reach the `db` service by name: # # cd /home/erik/MosswartOverlord # export BUILD_VERSION="$(date -u +%Y.%-m.%-d.%H%M)-$(git rev-parse --short HEAD)" # docker compose -f docker-compose.yml -f go-services/docker-compose.go.yml \ # build dereth-tracker-go # docker compose -f docker-compose.yml -f go-services/docker-compose.go.yml \ # up -d --no-deps dereth-tracker-go # # --no-deps keeps Compose from touching the already-running `db` (and anything # else). The service is loopback-bound (127.0.0.1:8770); external reach is only # ever via the host nginx `location /go/` block (added separately). services: dereth-tracker-go: build: context: ./go-services/tracker-go args: BUILD_VERSION: ${BUILD_VERSION:-dev} image: dereth-tracker-go:local container_name: dereth-tracker-go ports: - "127.0.0.1:8770:8770" environment: PORT: "8770" # Read-only use of the same dereth TimescaleDB the Python tracker writes. DATABASE_URL: "postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/dereth" # Point at the Go inventory service so the /go/ read stack is fully Go # end-to-end (browser -> Go tracker -> Go inventory -> read-only prod DBs). # inventory-go is read-only against the production inventory_db. INVENTORY_SERVICE_URL: "http://inventory-go:8772" # Same signing key as the Python tracker so the same login cookie verifies # on both during the parallel run. SECRET_KEY: "${SECRET_KEY}" LOG_LEVEL: "INFO" depends_on: - db restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Go port of discord-rare-monitor. Consumes the SAME Python /ws/live firehose # as the live Python bot. DRY-RUN by default (logs classifications, posts # nothing) so it can't double-post. To parallel-test for real, set a TEST # DISCORD_RARE_BOT_TOKEN + TEST channel IDs + DRY_RUN=0 here. discord-rare-monitor-go: build: context: ./go-services/discord-go args: BUILD_VERSION: ${BUILD_VERSION:-dev} container_name: discord-rare-monitor-go environment: DERETH_TRACKER_WS_URL: "ws://dereth-tracker:8765/ws/live" MONITOR_CHARACTER: "Dunking Rares" ICONS_DIR: "/icons" LOG_LEVEL: "INFO" # DISCORD_RARE_BOT_TOKEN: "" # set a TEST token to go live # DRY_RUN: "0" # required (with a token) to actually post # COMMON_RARE_CHANNEL_ID / GREAT_RARE_CHANNEL_ID / SAWATOLIFE_CHANNEL_ID / # ACLOG_CHANNEL_ID: set TEST channels before going live volumes: - ./discord-rare-monitor/icons:/icons:ro depends_on: - dereth-tracker restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ---- Phase 2: shadow ingest (fully isolated; production never touched) ---- # A SEPARATE TimescaleDB the Go tracker owns for shadow ingest. Isolated # volume + loopback port; the production dereth DB is never written. dereth-go-db: image: timescale/timescaledb:2.19.3-pg14 container_name: dereth-go-db ports: - "127.0.0.1:5434:5432" environment: POSTGRES_DB: "dereth_go" POSTGRES_USER: "postgres" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" volumes: - dereth-go-data:/var/lib/postgresql/data restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Shadow tracker instance: same image, but OWNS dereth-go-db (read-write) and # (once ingest lands) consumes the Python /ws/live firehose into it, so its # ingest output can be compared against production without writing to it. dereth-tracker-go-shadow: image: dereth-tracker-go:local container_name: dereth-tracker-go-shadow ports: - "127.0.0.1:8771:8771" environment: PORT: "8771" DATABASE_URL: "postgresql://postgres:${POSTGRES_PASSWORD}@dereth-go-db:5432/dereth_go" READ_ONLY: "false" # owns its DB; creates schema on boot INVENTORY_SERVICE_URL: "http://inventory-service:8000" SECRET_KEY: "${SECRET_KEY}" SHARED_SECRET: "${SHARED_SECRET}" # /ws/position plugin auth (cutover-ready) SHARED_SECRET_LEGACY: "${SHARED_SECRET_LEGACY:-}" # Replay the Python /ws/live firehose into the ingest handlers (shadow). SHADOW_INGEST_WS: "ws://dereth-tracker:8765/ws/live" LOG_LEVEL: "INFO" depends_on: - dereth-go-db restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Go port of inventory-service. Phase A: read side, READ-ONLY against the # production inventory_db, validated vs the Python service. Loopback :8772. inventory-go: build: context: ./go-services/inventory-go args: BUILD_VERSION: ${BUILD_VERSION:-dev} image: inventory-go:local container_name: inventory-go ports: - "127.0.0.1:8772:8772" environment: PORT: "8772" DATABASE_URL: "postgresql://inventory_user:${INVENTORY_DB_PASSWORD}@inventory-db:5432/inventory_db" READ_ONLY: "true" ENUM_DB_PATH: "/enums/comprehensive_enum_database_v2.json" LOG_LEVEL: "INFO" volumes: - ./inventory-service/comprehensive_enum_database_v2.json:/enums/comprehensive_enum_database_v2.json:ro depends_on: - inventory-db restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Phase C: isolated inventory DB the Go ingestion writes to (never production). inventory-go-db: image: postgres:14 container_name: inventory-go-db ports: - "127.0.0.1:5435:5432" environment: POSTGRES_DB: "inventory_db" POSTGRES_USER: "inventory_user" POSTGRES_PASSWORD: "${INVENTORY_DB_PASSWORD}" volumes: - inventory-go-data:/var/lib/postgresql/data restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Read-write inventory-go instance: owns inventory-go-db, exposes the ingestion # endpoints. Used to validate ingestion (POST a character's items, compare the # resulting normalized rows to production) without touching the production DB. inventory-go-shadow: image: inventory-go:local container_name: inventory-go-shadow ports: - "127.0.0.1:8773:8773" environment: PORT: "8773" DATABASE_URL: "postgresql://inventory_user:${INVENTORY_DB_PASSWORD}@inventory-go-db:5432/inventory_db" READ_ONLY: "false" ENUM_DB_PATH: "/enums/comprehensive_enum_database_v2.json" LOG_LEVEL: "INFO" volumes: - ./inventory-service/comprehensive_enum_database_v2.json:/enums/comprehensive_enum_database_v2.json:ro depends_on: - inventory-go-db restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" volumes: dereth-go-data: inventory-go-data: