DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Docker logs 没有应用日志,容器中的 nohup.out 却一直增长

nohup.out 有日志而 docker logs 没内容时,区分应用文件输出与 Docker 日志驱动;保留现有日志,再调整前台运行、标准流或持久文件采集。

应用在容器中用 nohup node index.js & 启动,nohup.out 有内容,docker logs 却看不到这些日志。Docker 通常收集容器进程的标准输出和标准错误,不会自动读取应用写入的任意日志文件。

先确定日志去了文件还是日志驱动,再决定查看文件或调整输出方式。本文适用于 Docker Engine 的普通容器;示例采用 Node.js,但判断方法也适用于其他写文件的应用。

看文件内容,先不用改启动方式

若已确认文件位置,下面是只读查看示例:

docker exec CONTAINER_ID tail -n 100 /usr/src/app/nohup.out

CONTAINER_ID 应替换成容器 ID 或容器名,文件路径也按实际工作目录调整。容器需处于运行状态并包含 tail;最小镜像未必有该工具。读取日志可能需要对应文件权限,不要为了临时查看日志把应用改为 root。

这里不必加 -t,输出可以直接保存在受控终端。使用 Compose 时,可对服务执行同样的命令:

docker compose exec -T app tail -n 100 /usr/src/app/nohup.out

app 是服务名示例,自定义项目参数须与部署一致。文件有新记录而 Docker 日志没有对应内容,说明当前输出路径至少有一部分在文件中,清理 Docker 缓存不能改变它。

如果容器已经退出,exec 不能使用。不要删除它;先用容器文件复制或已有挂载保存需要的日志,之后再调整启动方式。容器可写层中的文件在删除容器后不能按持久日志依赖。

Docker 日志驱动也要核对

查看目标容器的驱动配置:

docker inspect --format '{{json .HostConfig.LogConfig}}' CONTAINER_ID
docker logs --tail 100 CONTAINER_ID

若驱动是 none,Docker 不保存这组输出;外部驱动且本地双重日志缓存被关闭时,也可能需要去相应日志后端查看。先按现有日志架构定位数据,不能将所有空输出都认定为应用写文件。

驱动支持 docker logs,应用也确实输出到标准流,却仍暂时没有日志时,还应检查是否有新事件、输出缓冲及轮转保留范围。不要通过制造生产故障来获得一条错误日志。

长期处理:前台运行,输出到标准流

自有 Node.js 镜像的启动配置示例是:

WORKDIR /usr/src/app
CMD ["node", "index.js"]

镜像必须已经包含 Node.js 和应用,入口也不能再把它改为后台执行。应用日志配置需使用标准输出或标准错误;仅删除 nohup,不会自动让原本的文件日志配置变成标准输出。

Docker 容器由自己的主进程生命周期管理,通常不需要用 nohup 保持进程。主进程退出时容器可能结束;是否重启应使用适合业务的容器重启策略,而不是靠后台符号 &。

确实需要文件日志时,保留文件输出并配置持久挂载、轮转和采集器。不要同时对同一路径安排多个互相冲突的轮转程序。把文件链接到 /dev/stdout 只有在应用支持该方式、运行权限及日志重开行为已经明确时才适用,不应对已有文件直接覆盖。

切换前保存日志,切换后检查两件事

修改启动命令、镜像或日志驱动前,先保存现有文件日志以及旧配置,安排重建容器的维护窗口。日志驱动等创建配置的修改需要应用到新容器,重启现有容器不等于更新全部创建参数。回退时恢复原镜像、命令及日志配置;已经保存的日志应独立保留。

更新后既要确认应用持续提供服务,也要确认一次正常、可识别的业务事件出现在预期日志位置。Docker 日志中能看到启动信息,不代表后续业务日志也使用同一输出通道。若保留文件方案,则以采集器和轮转正常工作为成功标准,不能要求所有文件内容同时出现在 docker logs 中。