I had been trying to set up Cron & Anacron in Azure Web App for Containers (Stateful) for some time. I call them these Web App for Containers as stateful when the
WEBSITES_ENABLE_APP_SERVICE_STORAGE is set to
true in Application Settings. This means that
/home/ will be persisted across instance reboots. But do remember that any other directory is not persisted across reboots. This persistent storage is mounted on Azure Storage in the backend. This is required for applications like Drupal, Wordpress etc. In this post, we will use Apache as the Web Server.
You might be wondering why I used both Cron & Anacron? It was because the Azure Web App for Containers is a PaaS service and the instance could be moved from one host to another quite frequently. This means that if an instance reboot occurs when the
cron is scheduled to run, it would skip the job. And here comes
Anacron to the rescue. Anacron maintains a status file to keep track of when
cron.monthly. It doesnt keep track of hourly cron jobs unfortunately. But, once the container instance is started, it stays active for quite some time and you can be quite sure that your hourly cron jobs would run multiple times (<=24) in a day. That's fine because my aim was to rotate the logs which Apache generates daily (and a couple of other logs). If you have a website serving decent traffic, you can be sure that the Logfiles (generally in
/home/LogFiles) will consume several gigabytes. It is always a good idea to store the logs rather than not having them at the time of need.
To configure Logrotate, Cron & Anacron, follow the below steps -
Add the following section to your Web App for Containers
# Install Logrotate & Rsyslog and then configure it RUN set -ex \ && apt-get -y install logrotate rsyslog \ && rm -f /var/log/syslog \ && sed -i '/notifempty/a\ \tsu root root' /etc/logrotate.d/apache2 \ && cp /etc/cron.daily/logrotate /etc/cron.hourly/logrotate
You might see that I am running the Logrotate job every hour. This is good to test things and the default configuration file for Logrotate (Apache) is that it will rotate every day. Logrotate maintains its own status file to keep track.
Add the following section to remove the
apt-compatcron job. This is because this job contains various commands which are not available by default and it doesn't start immediately but a random time from 0-30 minutes. You can find more information over here.
# Remove apt-compat job from cron because it is stalling the cron jobs and we are anyways doing package cleaning later on in the image RUN set -ex \ && rm -f /etc/cron.daily/apt-compat
Install Anacron -
# Install Anacron to run jobs even if containers stop/reboot at the time of execution RUN set -ex \ && apt-get -y install anacron \ && chmod 777 /var/spool/anacron \ && mkdir -p /home/LogFiles/anacron \ && rm -f /var/spool/anacron/* \ && rmdir /var/spool/anacron \ && ln -s /home/LogFiles /var/spool/anacron
Now, we need to fix the following error which comes up when trying to start anacron -
Fix anacron not starting up because of policy.d stating -- "root@e12b813a8804:/home/LogFiles# /usr/sbin/invoke-rc.d anacron start
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start."
You can find more information as to why it is there over here. Add the following section as well -
RUN sed -i "s/^exit 101$/exit 0/" /usr/sbin/policy-rc.d
Now, in the
ENTRYPOINTscript (mine is
init_container.sh), add the following lines -
# Create symlink to Syslog so that we store logs as well touch /home/LogFiles/syslog ln -s /home/LogFiles/syslog /var/log/syslog # Create symlink to Logrotate status. We need to store the status file persistently because otherwise, Logrotate won't know. touch /var/lib/logrotate/status ln --symbolic /var/lib/logrotate/status /home/LogFiles/logrotate.status # Run Anacron to do the jobs. It will assume a random delay (check /etc/anacron for more details) before actually executing the jobs. Plus jobs automatically go to background. /usr/sbin/invoke-rc.d anacron start # Fire up necessary services service ssh start service cron start service rsyslog start
Once you push the image with these changes, after a couple of days, you would notice that logs are being rotated -