til flock
When you auto-deploy with a bash script from cron, the naive setup is something like this:
* * * * * /path/to/deploy.sh
This deploy.sh script checks if the current git hash is up to date with the main repo. If not, we want to trigger a new build locally and redeploy.
But this has an issue. Cron fires every minute, but docker build might a fair bit longer. Before you know it the second run starts while the first is still building, and now you've got two two builds getting into each-other.
It turns out there's a fix: wrap it in flock.
* * * * * flock -n /tmp/marimo-deploy.lock /path/to/deploy.sh
What flock does:
- It grabs an exclusive lock on the file
/tmp/marimo-deploy.lock. - It runs the command while holding it.
- Next, it releases the lock when the command exits.
The -n (non-blocking) flag is the key bit: if the lock is already held, flock exits immediately instead of queueing up. So if a build is still running when the next cron tick fires, the second invocation doesn't run.
One issue with the setup is that the deploy script could hang for whatever reason. So it's best to always add a timeout for this as well.
* * * * * flock -n /tmp/marimo-deploy.lock timeout 10m /path/to/deploy.sh
Feels like a nice pattern for those homelab moments where you don't want a webhook to push into your machine and you want to pull from GitHub on occasion instead.