文章内容

2025/12/8 22:34:48,作 者: 黄兵

docker-nginx-http3 日志不论转的问题

最近在使用 macbre/nginx-http3:latest 支持 HTTP/3(QUIC),具体可以参考这篇文章:Docker 部署支持 HTTP/3(QUIC)的 Nginx,但是日志没有正常轮转:

运行 docker 的命令:

docker run -d \
  --name nginx-quic \
  --restart=always \
  --add-host=host.docker.internal:host-gateway \
  -p 80:80 \
  -p 443:443/tcp \
  -p 443:443/udp \
  -v /root/nginx-quic/certs:/etc/nginx/certs \
  -v /root/nginx-quic/nginx.conf:/etc/nginx/nginx.conf \
  -v /root/nginx-quic/conf.d:/etc/nginx/conf.d \
  -v /root/nginx-quic/logs:/var/log/nginx \
  -v /var/CDN:/var/CDN \
  macbre/nginx-http3:latest

日志 没有按天拆分(access.log → access.log.1 / access-2025-12-09.log),最常见的原因只有 3 个,其中第 1 个是现在 99% 正在遇到的 核心问题

原因 1:挂载到 /var/log/nginx,覆盖了容器内的 logrotate 配置

上面挂载代码:

-v /root/nginx-quic/logs:/var/log/nginx

这会导致:

  • 覆盖容器内部的 /var/log/nginx 目录

  • 容器内的 logrotate 配置位于 /etc/logrotate.d/nginx,但是 logrotate 在容器中默认不运行

  • nginx 本身不会自动 rotate 日志

  • 所以日志永远不会切分,只会持续写入同一个 access.log

💥 属于典型:日志映射覆盖了容器的 logrotate + 容器本身没有 cron

原因 2:镜像 macbre/nginx-http3:latest 不包含 logrotate

经过检查这个镜像,它基于 Alpine/Linux,但:

  • 没有 logrotate

  • 没有 cron

  • Nginx 默认不会 rotate 日志

所以就算没有 volume mapping 也不会自动分割日志。

原因 3:你使用 QUIC/HTTP3 镜像,某些默认配置被移除

很多专用镜像(包括 macbre/nginx-http3)简化了系统,只保留 nginx 可执行文件,因此日志常规轮转机制都被移除。

🚀 解决方案(推荐 Strong)

方案 A:用 nginx 的 logrotate 容器解决(最通用)

新增一个 logrotate 容器,每天切分日志:

1. 创建 logrotate 配置 /root/nginx-quic/logrotate-nginx.conf
/root/nginx-quic/logs/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        docker exec nginx-quic nginx -s reopen
    endscript
}

2. 运行 cron+logrotate 容器:

docker run -d \
  --name nginx-logrotate \
  -v /root/nginx-quic/logrotate-nginx.conf:/etc/logrotate.d/nginx.conf \
  -v /root/nginx-quic/logs:/root/nginx-quic/logs \
  blacklabelops/logrotate

📌 优点:可靠、容器化、不破坏你的 nginx-quic 镜像

方案 B:Nginx 内部按小时切分(不依赖 logrotate)

直接让 Nginx 按时间命名日志:

修改 nginx.conf:
access_log /var/log/nginx/access_$time_iso8601.log;

但这种方式会生成无限多日志文件,不带 rotate,不推荐。

方案 C(最简单):每天一个日志 => 自己写一个 cron job

添加:/etc/cron.daily/nginx-logrotate.sh

内容:

#!/bin/bash
LOG_DIR="/root/nginx-quic/logs"
DATE=$(date +"%Y-%m-%d")

mv $LOG_DIR/access.log $LOG_DIR/access-$DATE.log
docker exec nginx-quic nginx -s reopen

然后:

chmod +x /etc/cron.daily/nginx-logrotate.sh

💡 为什么容器内不能自动 rotate?

因为:

  • Docker 容器没有 systemd

  • 没有 cron

  • 没有 logrotate 服务

  • 执行 nginx -s reopen 也无人触发

手动运行当然可以:

docker exec nginx-quic nginx -s reopen

但自动没人调用。

🔍 补充: swift-monitor 实时监控 access.log,即便日志拆分也没影响

swift-monitor 目前监听的是:

-v /root/nginx-quic/logs/access.log:/app/logs/access.log:ro

如果 logrotate 执行:

mv access.log access-2025-12-09.log
nginx -s reopen

swift-monitor 仍然会继续处理新的 access.log 文件,不会丢日志。


其它相关推荐:

1、Docker 容器开机自动启动

2、Dockerfile 构建系统与 GitHub

3、查看所有 docker 容器占用内存

4、HTTP/3 (QUIC) 的 Stream QUIC 是什么

5、Docker 部署支持 HTTP/3(QUIC)的 Nginx

分享到:

发表评论

评论列表