# audio2text — 一份 Dockerfile，CPU(dev) / GPU(prod) 双形态。
#   docker build --build-arg VARIANT=cpu -t audio2text:cpu .
#   docker build --build-arg VARIANT=gpu -t audio2text:gpu .
# 区别仅在基础镜像与 torch 轮子；Python 依赖列表完全一致。

ARG VARIANT=cpu
FROM python:3.12-slim AS base-cpu
# GPU 基础镜像带 CUDA 运行时，torch 可装 CUDA 轮子
FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04 AS base-gpu
RUN apt-get update -y && apt-get install -y --no-install-recommends \
        python3.12 python3.12-venv python3.12-dev python3-pip \
        && rm -rf /var/lib/apt/lists/* \
    && ln -sf /usr/bin/python3.12 /usr/local/bin/python3 \
    && ln -sf /usr/bin/python3.12 /usr/local/bin/python

FROM base-${VARIANT} AS final
ARG VARIANT
ENV VARIANT=${VARIANT} \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    HF_HOME=/models/huggingface \
    CT2_CACHE=/models/ctranslate2

# ffmpeg 是核心系统依赖，必须装
RUN apt-get update -y && apt-get install -y --no-install-recommends \
        ffmpeg ca-certificates patchelf \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt /app/requirements.txt


# CPU 装 CPU 版 torch；GPU 走默认 index（带 CUDA 的轮子）
RUN if [ "$VARIANT" = "cpu" ]; then \
        pip install --upgrade pip && \
        pip install torch --index-url https://download.pytorch.org/whl/cpu ; \
    else \
        pip install --upgrade pip && \
        pip install torch ; \
    fi
RUN pip install -r /app/requirements.txt

# ctranslate2 的 .so 带可执行栈标志（PT_GNU_STACK X），在某些内核 + Docker 组合下
# 会触发 "cannot enable executable stack as shared object requires"。用 patchelf
# 清掉该标志（改为 RW），无需放宽容器安全策略。
# 注意：库在 ctranslate2.libs/ 隐藏目录（pip wheel 拆分产物），不在 ctranslate2/ 包目录。
RUN for d in /usr/local/lib/python3.12/site-packages/ctranslate2.libs \
             /usr/local/lib/python3.12/site-packages/ctranslate2; do \
        [ -d "$d" ] && find "$d" -name '*.so*' \
            -exec patchelf --clear-execstack {} \; 2>/dev/null || true; \
    done; \
    python -c "import ctranslate2; print('ctranslate2 stack fix verified', ctranslate2.__version__)"

COPY app /app/app
COPY config.example.yaml /app/config.example.yaml

# 运行时数据：上传 / 中间产物 / 输出字幕 / 模型缓存
# 全部走 volume，镜像本身无状态、无敏感数据
VOLUME ["/data", "/models"]
ENV CONFIG_PATH=/app/config.yaml

EXPOSE 8000
CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
