【问题标题】:Logrotate - nginx logs not rotating inside docker containerLogrotate - nginx 日志不在 docker 容器内旋转
【发布时间】:2018-03-01 15:04:56
【问题描述】:

我有一个运行 nginx 的 docker 容器,它正在将日志写入/var/log/nginx Logrotate 安装在 docker 容器中,并且 nginx 的 logrotate 配置文件设置正确。尽管如此,logrotate 并没有自动轮换日志。通过logrotate -f /path/to/conf-file 手动强制日志轮换以轮换日志按预期工作。

我的结论是某些东西没有触发 cron 触发,但我找不到原因。

这是运行 nginx 的 docker 容器的 Dockerfile

FROM nginx:1.11

# Remove sym links from nginx image
RUN rm /var/log/nginx/access.log
RUN rm /var/log/nginx/error.log

# Install logrotate
RUN apt-get update && apt-get -y install logrotate

# Copy MyApp nginx config
COPY config/nginx.conf /etc/nginx/nginx.conf

#Copy logrotate nginx configuration
COPY config/logrotate.d/nginx /etc/logrotate.d/

还有 docker-compose 文件:

version: '2'
services:
  nginx:
    build: ./build
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./auth:/etc/nginx/auth
      - ./certs:/etc/nginx/certs
      - ./conf:/etc/nginx/conf
      - ./sites-enabled:/etc/nginx/sites-enabled
      - ./web:/etc/nginx/web
      - nginx_logs:/var/log/nginx
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "1"

volumes:
  nginx_logs:

networks:
  default:
    external:
      name: my-network

这里的内容是:/etc/logrotate.d/nginx

/var/log/nginx/*.log {
        daily
        dateext
        missingok
        rotate 30
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                [ -s /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
        endscript
}

/etc/cron.daily/logrotate的内容

#!/bin/sh

test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf

/etc/logrotate.conf 的内容

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0660 root utmp
    rotate 1
}

# system-specific logs may be configured here

有人可以指出为什么 nginx 日志没有被 logrotate 自动轮换的正确方向吗?

编辑

我可以将这个问题的根本原因追溯到容器上没有运行的 cron 服务。一个可能的解决方案是想办法让容器同时运行 nginx 和 cron 服务。

【问题讨论】:

    标签: docker nginx docker-compose dockerfile logrotate


    【解决方案1】:

    正如我对问题的编辑所述,问题是来自nginx:1.11CMD 只是启动nginx 进程。解决方法是将以下命令放在我的 Dockerfile 上

    CMD service cron start && nginx -g 'daemon off;'
    

    这将在 nginx:1.11 启动时启动 nginx 并启动 cron 服务。

    Dockerfile 看起来像:

    FROM nginx:1.11
    
    # Remove sym links from nginx image
    RUN rm /var/log/nginx/access.log
    RUN rm /var/log/nginx/error.log
    
    # Install logrotate
    RUN apt-get update && apt-get -y install logrotate
    
    # Copy MyApp nginx config
    COPY config/nginx.conf /etc/nginx/nginx.conf
    
    #Copy logrotate nginx configuration
    COPY config/logrotate.d/nginx /etc/logrotate.d/
    
    # Start nginx and cron as a service
    CMD service cron start && nginx -g 'daemon off;'
    

    【讨论】:

      【解决方案2】:

      我从this link找到了一个方法,其核心思想是在外面使用logrotate,conf如下:

      $ sudo vi /etc/logrotate.d/test
      /home/test/logs/*log {
          rotate 90
          missingok
          ifempty
          sharedscripts
          compress
          postrotate
              /usr/bin/docker exec nginx-test /bin/sh -c '/usr/sbin/nginx -s reopen > /dev/null 2>/dev/null'
          endscript
      }
      

      【讨论】:

      • 更好的是,在 postrotate 中执行此操作:if test $(docker ps -q --filter "name=nginx"); then docker exec nginx sh -c 'kill -USR1 $(cat /var/run/nginx.pid)'; fi
      • 我认为最好使用“docker inspect”更快,并且不需要任何特殊权限,请参阅此答案:stackoverflow.com/a/43745845/2056768
      • 代表 rzlvmp: Postrotate 脚本 100% 不工作,因为这里的 '-it' 参数错误。 Logrotate 没有日志,所以发现问题确实需要很长时间。
      • copytruncate 是你的朋友。这使您可以完全忽略postrotate。当然也有不利的一面:如果日志文件收到介于 copytruncate 之间的条目,您将丢失该条目。
      【解决方案3】:
      docker exec --user root `docker container ls --filter "name=nginx" --format "{{.Names}}"` nginx -s reopen
      

      【讨论】:

      • 请在您的答案中添加一些解释,以便其他人学习
      猜你喜欢
      • 2021-01-27
      • 2019-12-12
      • 1970-01-01
      • 2016-09-08
      • 2017-04-30
      • 2013-03-17
      • 2019-06-04
      • 2015-05-21
      • 2019-07-03
      相关资源
      最近更新 更多