You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose如何实现日志同时输出到文件与stdout且不影响容器启停

解决方案

方案1:使用进程替换避免管道导致的PID1异常

这是改造成本最低的方案,无需调整Docker Compose配置,仅修改启动脚本即可:

  1. 首先确认容器镜像包含Bash,将init-app.sh的首行shebang修改为:
#!/bin/bash
  1. 将原来的管道启动命令替换为进程替换写法:
# 启动应用,同时输出到stdout和日志文件,PID1仍为./app进程
exec ./app > >(tee -a /app/log.txt) 2>&1

原理说明

  • 进程替换>(tee ...)是Bash提供的特性,会在后台创建tee进程接收输出,不会引入管道子进程链
  • exec仍然会替换当前Shell进程为./app,保证./app是PID 1进程,可以正常接收Docker发送的停止信号
  • 你的Compose配置里已经开启了init: true,会自动处理孤儿进程回收,无需额外调整

方案2:备选(无需修改启动脚本)

如果你不想调整应用启动逻辑,可以利用Docker自带的日志收集能力实现需求:

  1. 保持原来仅输出到stdout的启动配置
  2. 在Docker Compose中补充日志驱动和挂载配置即可:
version: "3.8"
services:
    web:
        image: node:14
        command: sh "/app/scripts/init-app.sh"
        init: true
        volumes:
            - ./:/app
        logging:
          driver: "json-file"
          options:
            max-size: "10m"
            max-file: "3"

该方案下日志会同时存在于Docker的默认日志存储路径(可通过docker logs命令查看)和你挂载的宿主机目录下,同样不会影响容器启停逻辑。

验证方法

容器启动后执行以下命令,确认PID 1为你的应用进程即可:

docker exec <你的容器名/ID> ps 1

内容的提问来源于stack exchange,提问作者squarebrackets

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:09:03