FROM python:3.11-slim WORKDIR /app # 直连官方源不稳定,固定使用清华 PyPI 镜像 ENV PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple # P2-5: 创建非 root 用户(容器安全最佳实践) RUN groupadd --system profeto && useradd --system --gid profeto profeto # 可复现构建:先安装锁定版本的依赖(含哈希校验),再安装本项目 COPY pyproject.toml requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY src ./src RUN pip install --no-cache-dir . # 日志目录预创建: compose 运行时把 applogs 命名卷挂到 /app/logs, # 卷挂载点默认由 Docker 以 root:root 创建 —— 镜像内不预建的话, # 非 root 进程写日志会 PermissionError(Errno 13)。 # 命名卷为空且首次挂载时,Docker 会复制镜像内该目录的内容与属主, # 因此在这里 mkdir + chown 即可让卷目录归 profeto 所有。 RUN mkdir -p /app/logs # 将工作目录所有权移交给非 root 用户(含上面的日志目录) RUN chown -R profeto:profeto /app EXPOSE 8000 # 以非 root 用户运行 USER profeto # 启动时先跑迁移,再启 uvicorn CMD ["sh", "-c", "alembic upgrade head && uvicorn src.api.app:app --host 0.0.0.0 --port 8000"]