# Pin the Compose project name so `docker compose` from this directory always # targets the same stack. Without this, the project defaults to the directory # name (e.g. 'radio-tty'), which spins up a parallel stack that collides on # port 80 with an install started under a different name. name: hearthwave services: backend: build: context: . dockerfile: backend/Dockerfile args: COMPUTE_BACKEND: ${COMPUTE_BACKEND:-cpu} volumes: - ./data:/data - ./Voices:/app/Voices:ro # All Whisper models live here, including the two-tier final-pass model. # setup-cpu.sh stages both in one run and defaults the final model to # large-v3-turbo (~1.6 GB) — the one "auto" prefers: # bash setup-cpu.sh # small.en + large-v3-turbo # bash setup-cpu.sh --final-model distil-large-v3 # faster on long overs # bash setup-cpu.sh --final-model none # single-pass RX # New installs default whisper_model_final="auto" and pick the staged # model up automatically (turbo > distil > large-v3); a persisted "" # (explicit off) stays off until set to "auto" or a model name in the # Settings System tab. The final model lazy-loads on first finalized # utterance and adds ~1.5 GB RAM only while active. - ./Models:/app/backend/Models:ro # setup.sh writes PULSE_UID to .env — run it once before docker compose up - /run/user/${PULSE_UID:-1000}/pulse:/run/pulse:ro # Host timezone, so times spoken on air and embedded in reports/journals # are local (the container otherwise runs UTC). Non-Linux hosts: remove # this line and set a TZ environment variable instead (e.g. TZ=America/Detroit). - /etc/localtime:/etc/localtime:ro environment: - PULSE_SERVER=unix:/run/pulse/native devices: - /dev/snd:/dev/snd # MeshCore plugin: pass through the Companion radio's serial device. # Uncomment and match your host's port (also set it in the Server Config # panel → MeshCore device). Left commented so `docker compose up` works on # hosts without the device attached. # - /dev/ttyUSB0:/dev/ttyUSB0 restart: unless-stopped networks: - radio healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8765/health')"] interval: 10s timeout: 5s retries: 5 start_period: 20s frontend: build: context: ./frontend dockerfile: Dockerfile ports: - "80:8080" volumes: - ./data:/data:ro depends_on: backend: condition: service_started restart: unless-stopped networks: - radio networks: radio: driver: bridge