# Douanier — the CPU-deployable Audio-Intelligence API image (erable host).
#
# SRE reply (SRE.md): erable has NO GPU, ~2 GB RAM. The CLAP/torch stack does
# NOT fit, so this image ships ONLY the light V/A engine (librosa, no torch).
# One container, listens on :9780, SRE publishes it to 127.0.0.1:9780 behind
# the api.nech.pl nginx vhost + cert that's ALREADY live (returns 503 warming_up
# until this lands). The moment it's up, /v1/healthz goes green end-to-end.
#
#   build:  docker build -t douanier:latest armada/api
#   run:    see DEPLOY.md (env-file + /data volume + 127.0.0.1:9780 publish)

FROM python:3.12-slim AS base

# ffmpeg + libsndfile: librosa/soundfile decode uploaded mp3/m4a/wav/flac clips.
# Installed in one layer, apt lists removed, to keep the image lean.
RUN apt-get update && apt-get install -y --no-install-recommends \
        ffmpeg libsndfile1 \
    && rm -rf /var/lib/apt/lists/*

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=1 \
    # the deployable default: the torch-free engine. Override only on a GPU box.
    DOUANIER_EMOTION_ENGINE=light \
    # cache + DB land on a mounted volume (transient cache; DB is the backup target)
    DOUANIER_CACHE=/data/cache \
    DOUANIER_DB=/data/douanier.db

WORKDIR /app

# deps first (cached layer) — only the light stack, see requirements-deploy.txt
COPY requirements-deploy.txt .
RUN pip install -r requirements-deploy.txt

# then the app source (flat-module layout: run from /app, import config/engines.*)
COPY . .

# /data is the only writable state (cache + tokens DB). SRE mounts a 2 GB-capped dir here.
VOLUME ["/data"]
EXPOSE 9780

# single uvicorn worker — heavy work is serialized anyway; SRE owns the keep-alive
# systemd wrapper + restart policy. Bind all interfaces; the publish is localhost-only.
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "9780"]
