diff --git a/Dockerfile b/Dockerfile index f592023..bcba46a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,14 @@ RUN pip install --no-cache-dir -r requirements.txt COPY src ./src RUN pip install --no-cache-dir . -# 将工作目录所有权移交给非 root 用户 +# 日志目录预创建: 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 diff --git a/src/core/log_buffer.py b/src/core/log_buffer.py index 3dfb4e7..b3deda9 100644 --- a/src/core/log_buffer.py +++ b/src/core/log_buffer.py @@ -112,6 +112,15 @@ def setup_logging(level: str = "INFO", log_file: str = "") -> None: file_handler.addFilter(_SQLNoiseFilter()) root.addHandler(file_handler) logging.getLogger(__name__).info("文件日志已启用: %s", log_file) + except PermissionError: + # 容器场景最常见:挂载卷目录属主是 root,进程是非 root 用户。 + # 修复方向:镜像内预创建目录并 chown(Dockerfile),或重建空卷。 + logging.getLogger(__name__).warning( + "启用文件日志失败(%s):无写权限。容器部署请确认镜像已预创建该目录" + "并 chown 给运行用户(compose 卷挂载点默认 root 属主);" + "宿主机直跑请检查目录权限。本次仅保留 stdout/内存日志。", + log_file, + ) except Exception: logging.getLogger(__name__).warning( "启用文件日志失败(%s),仅保留 stdout/内存日志", log_file, exc_info=True,