If you run your own Mastodon instance, you might want to create a status page at some point to report on any downtime.
If you also use the docker version of Mastodon, like I do, then I hope you find at least some of this page useful to get you rolling.

Here's a brief run-down of how you can make a bash script to check on whether docker containers are healthy, then use cron to periodically ping a heartbeat to an uptime/status page service like BetterUptime.

What I use:

  • vim
  • cron
  • curl
  • bash
  • tmux

Start yourself a nice tmux session:


If you're new to tmux, here is a good cheat sheet.

Find out what your docker containers are named:

docker ps

Nice. Now open a new tmux tab with Ctrl+B (tmux control code), C (for create). Make sure you release Ctrl before you press C.

Make yourself a good ol' shell script file:

vim heartbeat.sh

Or use your editor of choice. If you want to use vim but you're new to it, here's a comprehensive cheat sheet. It just takes a lot of practice.

If using vim, enter insert mode with I.
Throw your shebang in there:


Now Ctrl+B, N (next) to look at your other tab for the name of a container you'd like to check on. Memorized it? Grand.
If you suck at memorizing, you can copy the name by doing this:
Ctrl+B, [, use the cursor keys to move your cursor over the first character of the container name, press Space to start selecting, cursor to last character, Enter. You done copied it, marvelous. Press Q to leave selection mode. Excellent job, tmux. Have a cookie.

Ctrl+B, N back. (If you have more than two tmux tabs open, you can use Ctrl+B, P to go to the previous)

We're going to check on the health of the container by using docker ps, but filtering based on the container name, and outputting only the status. Then we're going to pipe that output to grep to see if the status ends in "(healthy)":

if docker ps --filter "container_name" --format "{{.Status}}" | grep -q '(healthy)$'; then
    curl "https://heartbeat.url.here"

Use Ctrl+B, ] to paste the container name you copied earlier in place of container_name. The -q flag on grep is for quiet; the command won't output the whole line it finds the string on, it only performs a logic check, which is all we need for an if statement.
If it finds that the status ends in "(healthy)" then it will hit the url in the curl command. Here's where you put the URL your uptime services tells you to ping for your heartbeat.

You can add as many of these if statements as you need for your various containers.

Leave insert mode in vim with Esc, then save and close your script file (:wq in vim) and make it executable with:

chmod u+x heartbeat.sh

Now, to make this heart beat, we'll add it to crontab:

crontab -e

Add a new line to the end.
Check every minute:

* * * * * /path/to/heartbeat.sh

Or check every two minutes:

*/2 * * * * /path/to/heartbeat.sh

Or replace 2 with the minute interval of your choice, just make sure the uptime service expects the heartbeat that often.
Save your crontab, and immediately your server will start to ping your heartbeat URL unless a service goes down or leaves the "healthy" state.

Previous Post Next Post

Setting up a heartbeat script for docker images