生产实测: applogs 命名卷挂到 /app/logs 时挂载点由 Docker 以 root:root 创建,而非 root 进程(profeto)写入 app.log 时 PermissionError(Errno 13), best-effort 降级生效但文件日志实际未启用。 - Dockerfile: 镜像内预创建 /app/logs 并 chown(chown -R 已有,覆盖新目录); 命名卷为空且首次挂载时 Docker 会复制镜像目录属主,重建镜像即可修复 - log_buffer: PermissionError 单独捕获,warning 给出可操作的排查方向 (镜像预建目录/chown/重建空卷),其余异常仍保持原通用降级
35 lines
1.2 KiB
Docker
35 lines
1.2 KiB
Docker
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"]
|