Files

68 lines
2.8 KiB
Docker

# =============================================================================
# SayIt Backend — GPU Docker Image
# =============================================================================
# Layer strategy:
# 1. CUDA base + system deps (rarely changes)
# 2. Python dependencies (changes on pip update)
# 3. ASR model (Qwen3-ASR-1.7B) (rarely changes, ~4.4GB)
# 4. Application code + prompts (changes often, ~few MB)
# =============================================================================
# --- Layer 1: CUDA base ---
FROM nvidia/cuda:12.4.1-runtime-ubuntu22.04 AS base
ENV DEBIAN_FRONTEND=noninteractive \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
HF_HOME=/app/models
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 python3-venv python3-dev python3-pip \
ffmpeg build-essential curl openssl sox libsox-dev && \
ln -sf /usr/bin/python3 /usr/bin/python && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# --- Layer 2: Python dependencies ---
COPY backend/requirements.txt /tmp/requirements.txt
ARG TORCH_INDEX_URL=https://download.pytorch.org/whl/cu124
RUN python -m pip install --upgrade pip && \
pip install torch torchaudio --index-url ${TORCH_INDEX_URL} && \
pip install numpy && \
pip install --no-build-isolation -r /tmp/requirements.txt && \
rm /tmp/requirements.txt
# --- Layer 3: ASR model + VAD model (cached in /app/models, readable by all users) ---
RUN mkdir -p /app/models && \
python -c "from huggingface_hub import snapshot_download; snapshot_download('Qwen/Qwen3-ASR-1.7B')" && \
python -c "from modelscope.hub.snapshot_download import snapshot_download; snapshot_download('iic/speech_fsmn_vad_zh-cn-16k-common-pytorch')" && \
chmod -R a+rwX /app/models /root /root/.cache 2>/dev/null; true
# --- Layer 4: Application code + built-in defaults ---
RUN useradd -m -s /bin/bash sayit && \
mkdir -p /app/runtime /app/certs && \
chown -R sayit:sayit /app/runtime && \
chmod -R a+rX /root/.cache 2>/dev/null; true
COPY --chown=sayit:sayit backend/app /app/backend/app
COPY --chown=sayit:sayit web /app/web
COPY --chown=sayit:sayit prompts /app/prompts
COPY --chown=sayit:sayit config.example.yaml /app/config.yaml
# Generate self-signed TLS certificate (for browser microphone API over HTTPS)
RUN openssl req -x509 -newkey rsa:2048 -keyout /app/certs/dev.key \
-out /app/certs/dev.crt -days 3650 -nodes \
-subj "/CN=sayit-local" 2>/dev/null && \
chown -R sayit:sayit /app/certs
USER sayit
EXPOSE 8000 8443
HEALTHCHECK --interval=30s --timeout=5s --start-period=120s --retries=3 \
CMD curl -sf http://localhost:8000/healthz || exit 1
WORKDIR /app/backend
COPY --chown=sayit:sayit backend/entrypoint.sh /app/backend/entrypoint.sh
ENTRYPOINT ["/bin/bash", "/app/backend/entrypoint.sh"]