68 lines
2.8 KiB
Docker
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"]
|