# mimir-inbox — large-document / book ingestion UI over the muninn-gate API (#377).
# Deployed on corviduo-dev (10.250.50.152), co-located with muninn-gate (:8090)
# and the worldtree-personal muninn watcher. Operator ruled co-location 2026-08-01
# (reversing the earlier off-box/NFS plan); worldtree-dev approved the box
# placement. infra-ops-managed stack, separate from the worldtree CI/CD compose.
#
# Image built out-of-band (all deps public PyPI, no secret needed):
#   docker build -t mimir-inbox:0.0.1 .
#
# Runtime config (incl. the bearer-key secret) lives on the server in a gitignored
# .env next to this compose; repo carries the redacted .env.example.
services:
  mimir-inbox:
    image: mimir-inbox:0.0.1
    container_name: mimir-inbox
    restart: unless-stopped
    # uid 1000 (vh) — the SOLE writer to the staging root (INV-MI-3), which is
    # provisioned 1000:1000. Matches the corviduo-dev muninn stack (gate is 1000).
    user: "1000:1000"
    # Host networking: the WG-internal bind lands directly on corviduo-dev, and
    # MUNINN_GATE_URL=http://10.250.50.152:8090 reaches the co-located gate (whose
    # own bind is host-network on that address).
    network_mode: host
    # The 7 runtime vars incl. the secret. The two DEV-ONLY drift-guard vars
    # (WORLDTREE_CONFIG_PATH, MUNINN_GATE_REPO) are deliberately absent — they
    # must not be set in the container.
    env_file:
      - .env
    command:
      - uvicorn
      - --factory
      - mimir_inbox.app:create_app
      - --host
      - "10.250.50.152"
      - --port
      - "8091"
    volumes:
      # Shared staging root — mimir-inbox is the SOLE WRITER; the gate + watcher
      # bind this SAME absolute path :ro. A corviduo-dev-LOCAL dir (path identity
      # is the real constraint; the watcher opens staged files IN PLACE at claim
      # — worldtree-dev, core/muninn/runner.py:362-367 — so co-location buys path
      # identity outright and nothing crosses a device boundary).
      - /mnt/muninn-staging/mimir-inbox:/mnt/muninn-staging/mimir-inbox:rw
    healthcheck:
      # LIVENESS ONLY — a TCP connect proves uvicorn is bound, WITHOUT coupling
      # container health to gate reachability. A gate outage must NOT restart
      # mimir-inbox; the health banner surfaces that state instead (same lesson
      # as the gate's /ping-not-/health probe).
      test: ["CMD", "python", "-c", "import socket; socket.create_connection(('10.250.50.152',8091),3).close()"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    labels:
      - homepage.group=Worldtree
      - homepage.name=Mimir Inbox
      - homepage.icon=mdi-book-arrow-right
      - homepage.description=Large-document ingestion UI for the Muninn KB (#377)
      - homepage.href=http://10.250.50.152:8091/
