Get a Docker Container Notification on Your Phone the Moment One Crashes
Get a Docker container notification on your iPhone the moment a container dies — a 10-line bash script, no agent to install, no dashboard to babysit.
One of the containers in your compose stack exits at 3 a.m. The restart policy retries it five times, gives up, and moves on. Your API has been returning 500s for six hours — and the first you hear about it is a support ticket at breakfast.
Docker's restart policies are great right up until they aren't. restart: unless-stopped will happily loop a crashing container forever without telling a soul, and a container that exits cleanly and stays down doesn't page anyone at all. docker ps only helps when you're already staring at it. What you actually want is the opposite: the container tells you.
The fix is smaller than the problem. Docker already keeps a running log of every container that starts, stops, or dies — you just have to listen to it. Tail that log, POST one line to your phone whenever something falls over, and you're done. Ten lines of bash, no monitoring agent, no Prometheus stack to stand up.
The idea: watch container state, ping on change
Docker already emits a live stream of lifecycle events — start, die, oom, health_status, the lot. docker events hands you that stream on stdout. You filter for the events you care about and pipe each one into a single curl call. That's the entire design.
The push itself is one POST to the TheNotificationApp API — the exact shape is in the API reference: an app_key header, a JSON body with title and body. Nothing else to wire up.
The 10-line version: alert when any container dies
Grab a free key from the app first, export it, then run this:
#!/usr/bin/env bash
# notify-on-die.sh — ping your phone whenever a container dies
docker events \
--filter 'event=die' \
--format '{{.Actor.Attributes.name}} {{.Actor.Attributes.exitCode}}' |
while read -r name exit_code; do
curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: $APP_KEY" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"Container down: $name\",
\"body\": \"$name exited with code $exit_code\"
}"
doneRun it with APP_KEY=your_key ./notify-on-die.sh and leave it going. Every time a container in the stack dies — web, db, that flaky queue worker — you get a push with its name and exit code. An exit code of 137? That's an OOM kill. 1? The app threw on startup. You already know where to look before you've opened the laptop.
Only the unhealthy ones (if you use HEALTHCHECK)
Exit codes catch hard crashes, but a container can be technically "running" and completely wedged — accepting connections, answering nothing. If your images define a HEALTHCHECK, Docker emits a health_status event on every transition. Watch for the unhealthy ones:
#!/usr/bin/env bash
# notify-on-unhealthy.sh
docker events \
--filter 'event=health_status' \
--format '{{.Actor.Attributes.name}} {{.Action}}' |
while read -r name rest; do
case "$rest" in
*unhealthy*)
curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: $APP_KEY" \
-H "Content-Type: application/json" \
-d "{\"title\": \"Unhealthy: $name\", \"body\": \"$name failed its health check\"}" ;;
esac
doneNow you hear about the slow rot too — the container that's up but not okay — not just the ones that fall over outright.
Prefer cron? A poll-based version
If you'd rather not keep a long-running process alive, check state on a schedule instead. List the containers you expect to be up, and shout if any of them isn't:
#!/usr/bin/env bash
# docker-watch.sh — run from cron
EXPECTED="web db redis"
for name in $EXPECTED; do
state=$(docker inspect -f '{{.State.Running}}' "$name" 2>/dev/null)
if [ "$state" != "true" ]; then
curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: $APP_KEY" \
-H "Content-Type: application/json" \
-d "{\"title\": \"Container down: $name\", \"body\": \"$name is not running\"}"
fi
doneDrop it in your crontab to run every five minutes:
*/5 * * * * APP_KEY=your_key /path/to/docker-watch.shSame idea as the classic cron job failure alert — just pointed at container state instead of an exit code.
Real talk: don't let a crash loop drain your quota
One honest catch. The free tier is 100 notifications total, not per month — and a container stuck in a restart loop can emit a die event every few seconds. Wire the first script straight to your phone with no guard, and a single bad night of flapping will burn the whole 100 before you wake up. Pro lifts it to 1,000 a month for $2.99, but a bigger bucket isn't the real fix. Alert on the transition — down once, up once — not on every flap. The same state-change trick from the server monitoring guide applies here: track the last known state in a file, and only send when it actually changes.
Where to go from here
Wrap the events watcher in a small systemd unit (or its own tiny container with restart: always) so the watcher itself comes back after a reboot. Add a link field pointing at your logs or dashboard, so the notification is one tap from the fix. And if OOM kills are your recurring nightmare, filter on event=oom specifically — you'll know a container got starved before the restart even finishes.
That's the whole trick: Docker already knows the second a container dies, and now so does your phone. Worth a look if you're tired of hearing about dead containers from your users first — TheNotificationApp is free to start, stores nothing, and is hosted in Switzerland.
Stop babysitting your scripts.
Free to download. Free tier available. Swiss-hosted, private by design.