日志轮换 - 在Docker容器中nginx日志没有轮换

32
我有一个运行Nginx的Docker容器,它将日志写入/var/log/nginx。Docker容器中安装了Logrotate,并且为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服务。

3个回答

21
根据我在问题编辑中的说明,问题在于来自nginx:1.11CMD仅启动了nginx进程。解决方法是在我的Dockerfile中添加以下命令。
CMD service cron start && nginx -g 'daemon off;'

这将启动nginx,就像nginx:1.11一样启动它,并且还会启动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;'

16

我从这个链接中找到了一个方法,其核心思想是在外部使用logrotate,配置如下:

$ 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
}

3
在postrotate中执行以下操作更好:if test $(docker ps -q --filter "name=nginx"); then docker exec nginx sh -c 'kill -USR1 $(cat /var/run/nginx.pid)'; fi - ruuter
1
我认为最好使用"docker inspect"命令,它更快捷,也不需要任何特殊权限。请参考此答案:https://dev59.com/e6Hia4cB1Zd3GeqPS2ZX#43745845 - EddieM
1
代表rzlvmp:Postrotate脚本完全不起作用,因为这里的“-it”参数是错误的。Logrotate没有日志,所以找到问题可能需要很长时间。 - user1600649
copytruncate 是你的好朋友。这使你可以完全忽略 postrotate。当然,有一个缺点:如果日志文件在 copytruncate 之间接收到一个条目,那么你将会失去该条目。 - EdwardTeach

-3
docker exec --user root `docker container ls --filter "name=nginx" --format "{{.Names}}"` nginx -s reopen

6
请在您的回答中添加一些解释,以便其他人可以从中学习。 - Nico Haase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接