首页 > 解决方案 > 限制 docker nginx 日志文件大小

问题描述

我们在 docker compose 设置中使用 docker 镜像 nginx:stable-apline:

core-nginx:
    image: nginx:stable-alpine
    restart: always
    environment:
      - NGINX_HOST=${NGINX_HOST}
      - NGINX_PORT=${NGINX_PORT}
      - NGINX_APP_HOST=${NGINX_APP_HOST}
    volumes:
      - ./nginx/conf/dev.template:/tmp/default.template
      - ./log/:/var/log/nginx/
    depends_on:
      - core-app
    command: /bin/sh -c "envsubst '$$NGINX_HOST $$NGINX_PORT $$NGINX_APP_HOST'< /tmp/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
    ports:
      - 5001:5001

在此设置中,日志文件的大小不受限制。

任何人都可以提供一些指示如何限制 access.log 和 error.log 的大小吗?

标签: dockernginxlogging

解决方案


有几种方法可以解决这个问题。

Docker 日志驱动程序

您使用的 Nginx 容器默认配置access.logto go tostdouterror.logto go to stderr。如果您要删除要安装的卷/var/log/nginx,您将获得此默认行为,这意味着您将能够通过 Docker 日志驱动程序管理日志。默认的json-file 日志驱动程序有一个max-size选项可以完全满足您的要求。

使用此解决方案,您将使用该docker logs命令检查 nginx 日志。

容器化日志轮换

如果你真的想记录到本地文件而不是使用 Docker 日志驱动程序,你可以添加第二个容器到你的docker-compose.yml那个:

  • 运行 cron
  • 定期调用脚本重命名日志文件
  • nginx向进程发送适当的信号

为了使所有这些工作:

  • cron 容器需要访问 nginx 日志。因为您将日志存储在一个卷上,所以您可以将相同的卷挂载到 cron 容器中。
  • cron 容器需要在 nginx pid 命名空间中运行才能发送重启信号。这是 的--pid=container:...选项docker run,或 中的pid:选项docker-compose.yml

例如,像这样:

version: "3"

services:
  nginx:
    image: nginx:stable-alpine
    restart: always
    volumes:
      - ./nginx-logs:/var/log/nginx
      - nginx-run:/var/run
    ports:
      - 8080:80

  logrotate:
    image: alpine:3.13
    restart: always
    volumes:
      - ./nginx-logs:/var/log/nginx
      - nginx-run:/var/run
      - ./cron.d:/etc/periodic/daily
    pid: service:nginx
    command: ["crond", "-f", "-L", "/dev/stdout"]


volumes:
  nginx-run:

cron.d我的本地目录中,我的rotate-nginx-logs(mode 0755) 如下所示:

#!/bin/sh

pidfile=/var/run/nginx.pid
logdir=/var/log/nginx

if [ -f "$pidfile" ]; then
    echo "rotating nginx logs"
    for logfile in access error; do
        mv ${logdir}/${logfile}.log ${logdir}/${logfile}.log.old
    done

    kill -HUP $(cat "$pidfile")
fi

有了这个配置,logrotate容器将每天重命名一次日志并向 nginx 发送USR1信号,使其重新打开其日志文件。


我的偏好通常是第一个解决方案(使用 Docker 收集日志并使用 Docker 日志驱动程序选项来管理日志轮换),因为它降低了最终解决方案的复杂性。


推荐阅读