0

I have a Ruby on Rails application running on Docker and would like to rotate my production logs every day. In the spirit of keeping everything self-contained, I would like to keep the log rotation on Docker itself as well. Here's the logrotate configuration on my Docker container:

/etc/logrotate.conf

# rotate log files weekly
weekly

# keep 1 week worth of backlogs
rotate 1

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

# use date as a suffix of the rotated file
dateext

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

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

# system-specific logs may be also be configured here.

# Rotate Rails logs
/myapp/log/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  copytruncate
}

Permissions for /etc/logrotate.conf:

-rw-r--r-- 1 root root 656 Jul 13 02:06 /etc/logrotate.conf

After a day, my log file has not been rotated. I know this isn't an issue with my container being recreated because it's been running for 6 days.

When I go to test it, I get an error message on every line:


> logrotate -d /myapp/log/production.log
  ...
> error: production.log:56257 unknown option 'I' -- ignoring line
> error: production.log:56258 unknown option 'I' -- ignoring line
> error: production.log:56259 unknown option 'I' -- ignoring line

Here are the permissions on my production.log:

-rw-r--r-- 1 root root 10868754 Jul 14 12:42 /myapp/log/production.log

And when I check what's in the log file, the contents are indeed there:

I, [2022-07-13T02:48:23.666904 #1]  INFO -- : Raven 3.1.0 ready to catch errors
I, [2022-07-13T03:00:18.483790 #8]  INFO -- : Raven 3.1.0 ready to catch errors
I, [2022-07-13T03:00:34.021416 #22]  INFO -- : Started GET "/healthcheck" for xxx.xx.xx.xx at 2022-07-13 03:00:34 +0000
I, [2022-07-13T03:00:34.026047 #22]  INFO -- : Processing by HealthcheckController#show as HTML
I, [2022-07-13T03:00:34.027170 #29]  INFO -- : Started GET "/healthcheck" for xxx.xx.xx.xx at 2022-07-13 03:00:34 +0000
I, [2022-07-13T03:00:34.031331 #29]  INFO -- : Processing by HealthcheckController#show as HTML
I, [2022-07-13T03:00:34.038132 #20]  INFO -- : Started GET "/healthcheck" for xxx.xx.xx.xx at 2022-07-13 03:00:34 +0000
I, [2022-07-13T03:00:34.042771 #20]  INFO -- : Processing by HealthcheckController#show as HTML
I, [2022-07-13T03:00:34.040177 #20]  INFO -- : Started GET "/healthcheck" for xxx.xx.xx.xx at 2022-07-13 03:00:34 +0000
I, [2022-07-13T03:00:34.221546 #20]  INFO -- : Processing by HealthcheckController#show as HTML

What can I do to get logrotate to rotate my logs?

Alexander
  • 3,959
  • 2
  • 31
  • 58
  • You have to pass the configuration `/etc/logrotate.conf` as an argument rather than the log file when running your debug command: `logrotate -d /etc/logrotate.conf`. – β.εηοιτ.βε Jul 14 '22 at 13:05
  • @β.εηοιτ.βε Ahh thank you! Looks like there was no issue with my config. I forced logrotate to start, it worked! [This SO post](https://stackoverflow.com/a/46365627/2430657) revealed that `cron` isn't running on my Docker container, so I need to start it. – Alexander Jul 14 '22 at 13:30
  • Don't do that, it is not a good idea to have systemd and crond on a container! Rather do what should be with containers, send your stdin/stderr, so Docker will handle them and implement a log driver on the machine that supports your Docker. https://www.datadoghq.com/blog/docker-logging/ – β.εηοιτ.βε Jul 14 '22 at 13:36
  • @β.εηοιτ.βε Thank you for the information; I will look into it. What if my application has regularly scheduled background jobs that rely on cron for scheduling? Should that be handled by an external cron service? – Alexander Jul 14 '22 at 13:40

1 Answers1

0

Thanks to @β.εηοιτ.βε, I found out that I needed to specify the config file, not the log file, in the logrotate arguments when debugging it, like this:

logrotate -d /etc/logrotate.conf

That revealed there was nothing wrong with my configuration. Then I forced a log rotation with:

logrotate -f /etc/logrotate.conf

And it worked! As for why my log file was not rotated after a day, this SO post suggested that cron may not be running in the container, which I found out to be true in my case:

> service cron status
[FAIL] cron is not running ... failed!

I updated my Dockerfile's entrypoint to start cron. So it looks like this now:

Dockerfile

...

CMD /bin/bash

ENTRYPOINT [ "./docker/web-entrypoint.sh" ]

docker/web-entrypoint.sh

#!/bin/sh
set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

cron service start # New line added
bundle exec rails s -b 0.0.0.0 -p 3000

Now it's all working!

Alexander
  • 3,959
  • 2
  • 31
  • 58