Logrotate - nginx logs not rotating inside docker container
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
}
Related videos on Youtube
dazito
Updated on October 23, 2020Comments
-
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 vialogrotate -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 about 4 yearsBetter 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 about 4 yearsPlease add some explanation to your answer by editing it, such that others can learn from it
-
EddieM over 3 yearsI 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 over 3 yearsOn 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 over 2 years
copytruncate
is your friend. This allows you to completely ignorepostrotate
. There is of course a down-side: if the log file receives an entry between thecopy
andtruncate
, you'll lose that entry.