# ---- AirShelf core backend: Django + DRF + gunicorn / celery ---- FROM docker.m.daocloud.io/python:3.12-slim ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PIP_NO_CACHE_DIR=1 \ PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ WORKDIR /app # 视频导出(stage5 拼接)靠 ffmpeg 二进制;字幕用 Pillow 渲染 PNG 需中文字体(fonts-noto-cjk), # 否则线上导出报 "No such file or directory: 'ffmpeg'" / 中文字幕变方块。slim 镜像默认两者都无。 # 换阿里云 apt 源避免国内构建超时(兼容 bookworm 的 deb822 与旧 sources.list 两种格式)。 RUN (sed -i 's|deb.debian.org|mirrors.aliyun.com|g; s|security.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources 2>/dev/null \ || sed -i 's|deb.debian.org|mirrors.aliyun.com|g; s|security.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list 2>/dev/null || true) \ && apt-get update \ && apt-get install -y --no-install-recommends ffmpeg fonts-noto-cjk \ && rm -rf /var/lib/apt/lists/* # PyMySQL is pure-python (install_as_MySQLdb), boto3/gunicorn need no C deps, # so the slim image is enough — no build-essential required. COPY requirements.txt . RUN pip install --upgrade pip && pip install -r requirements.txt COPY . . # Collected admin/static lands here; served by WhiteNoise (see settings/production.py) RUN mkdir -p /app/staticfiles COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod +x /usr/local/bin/docker-entrypoint.sh EXPOSE 8000 ENTRYPOINT ["docker-entrypoint.sh"] # timeout 300:前端已把多图生成拆成「每张一条请求」,单张约 30s;300s 给慢 ARK 留充足余量, # 不再因一条请求串行出多张而超时(旧 120s 下生成 4 张必被 worker 强杀 → 500)。 CMD ["gunicorn", "airshelf.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3", "--timeout", "300"]