I just got back from the iPC/iJS conference in Munich and had a great time. I brought back 7 lessons I learned (more on that later) and inspiration for other things. One of them was to get a handle of managing all of our cronjobs. We have 2 servers and several Elastic Beanstalk applications, all of which have their own cronjob setups. I’ve been having them email a group email address and tucking them away and reviewing them every once in a while to see if there were any errors. This led me to the thought that there’s got to be a better way. I started thinking about how I could append a ping to a centralized service after each cron job and that service could monitor the jobs and then ping me if anything goes missing. Then I thought, wait a secon…
I just got back from the iPC/iJS conference in Munich and had a great time. I brought back 7 lessons I learned (more on that later) and inspiration for other things. One of them was to get a handle of managing all of our cronjobs. We have 2 servers and several Elastic Beanstalk applications, all of which have their own cronjob setups. I’ve been having them email a group email address and tucking them away and reviewing them every once in a while to see if there were any errors. This led me to the thought that there’s got to be a better way. I started thinking about how I could append a ping to a centralized service after each cron job and that service could monitor the jobs and then ping me if anything goes missing. Then I thought, wait a second ... maybe someone else has already done this. I DDG’d (DuckDuckGo’d) it and came across this writeup with several solutions. I checked out Healthchecks.io and upon digging deeper, saw that their software was available via a Docker image that you could self-host.
So I created a new Elastic Beanstalk Docker application with this Dockerfile:
FROM healthchecks/healthchecks:latest
# Expose port 8000 (default for healthchecks)
EXPOSE 8000
# Environment variables for healthchecks configuration
# You can customize these as needed
ENV SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https \
DEBUG=False \
DEFAULT_FROM_EMAIL=healthchecks@example.com \
SECRET_KEY=RANDOM_SSL_SECRET_KEY \
ADMINS=admin@example.com \
DB=mysql \
DB_HOST={{DB_HOST}} \
DB_NAME={{DB_NAME}} \
DB_PASSWORD={{DB_PASSWORD}} \
DB_USER={{DB_USER}} \
EMAIL_HOST={{STMP_HOST}} \
EMAIL_HOST_USER={{STMP_USER}} \
EMAIL_HOST_PASSWORD={{STMP_PASSWORD}} \
SITE_NAME="Example Healthchecks" \
SITE_ROOT={{SITE_ROOT}} \
RP_ID=hc.example.com
# The healthchecks image already has the entrypoint configured
Then I spun up a single spot instance environment for the application and it generated a domain and then I was able to sign up on the website and get going with setting up the various cronjobs. The process starts with creating a check and it will give you the URL and Usage Examples on how to integrate the ping with the cronjob. Most of my cronjobs were in /etc/crontab, so I just appended the && curl ... cmd to the end of each one with the specific cronjob.
I’ve been amazed how much thought and features are baked into the software. Yes, it can send you email, but it can also notify you via Slack, Google Chat, Slack, Microsoft Teams, etc. It has passkey authentication support, timezone support, badges, and great documentation.
So now I have all of our various cronjobs plugged in. Come to find out, we have 55!
And through the inventory process, I found that there was a cronjob that had not been running successfully for quite a while, so this was a great exercise.
For extra measure, I set up a new subdomain and pointed the A record to an alias of the Elastic Beanstalk, which allowed me to have a dedicated hostname. I also wanted SSL/TLS, so that required some certbot setup.
Cover Image Credit: https://www.pickpik.com/alarm-clock-museum-a-collection-of-an-antique-clock-gray-88737