Logrotate - nginx logs not rotating inside docker container

27,513

Solution 1

As stated on the edit on my question the problem was that CMD from nginx:1.11 was only starting the nginx process. A work around is to place the following command on my Dockerfile

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

This will start nginx as nginx:1.11 starts it and well as start the cron service.

The Dockerfile would look something like:

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;'

Solution 2

i found a method from this link, its core idea is use logrotate outside, and conf is as below:

$ 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
}
Share:
27,513

Related videos on Youtube

dazito
Author by

dazito

Updated on October 23, 2020

Comments

  • dazito
    dazito over 3 years

    I've a docker container running nginx which is writing logs to /var/log/nginx Logrotate is installed in the docker container and the logrotate config file for nginx is set up correctly. Still, the logs are not being automatically rotated by logrotate. Manually forcing log rotate to rotate the logs via logrotate -f /path/to/conf-file works as expected.

    My conclusion is that something is not triggering the cron to fire but I can't find the reason.

    Here's the Dockerfile for the docker container running nginx:

    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/
    

    And the docker-compose file:

    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
    

    Here's the content of: /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
    }
    

    Content of /etc/cron.daily/logrotate

    #!/bin/sh
    
    test -x /usr/sbin/logrotate || exit 0
    /usr/sbin/logrotate /etc/logrotate.conf
    

    Content of /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
    

    Can someone point me in the right direction to why nginx logs are not being automatically rotated by logrotate?

    EDIT

    I can trace the root cause of this problem to the cron service not being run on the container. A possible solution is to find a way to make the container run both nginx and cron service at the same time.

  • ruuter
    ruuter about 4 years
    Better yet, do this in postrotate: if test $(docker ps -q --filter "name=nginx"); then docker exec nginx sh -c 'kill -USR1 $(cat /var/run/nginx.pid)'; fi
  • Nico Haase
    Nico Haase about 4 years
    Please add some explanation to your answer by editing it, such that others can learn from it
  • EddieM
    EddieM over 3 years
    I think it is better to use "docker inspect" much quicker and doesn't require any special privileges, see this answer: stackoverflow.com/a/43745845/2056768
  • Admin
    Admin over 3 years
    On behalf of rzlvmp: Postrotate script is 100% not working, because of '-it' parameters wrong here. Logrotate don't has logs, so finding the problem really may take long time.
  • EdwardTeach
    EdwardTeach over 2 years
    copytruncate is your friend. This allows you to completely ignore postrotate. There is of course a down-side: if the log file receives an entry between the copy and truncate, you'll lose that entry.