Skip to content

Instantly share code, notes, and snippets.

@ghidinelli
Last active April 19, 2023 23:41
Show Gist options
  • Save ghidinelli/f88d40243e0879ba382022120c086d96 to your computer and use it in GitHub Desktop.
Save ghidinelli/f88d40243e0879ba382022120c086d96 to your computer and use it in GitHub Desktop.
Docker entrypoint wrapper runs shutdown tasks before a container exits
#!/bin/bash
# exit if any pipeline exits non-zero
set -e
# capture stdout and stderr
exec 2>&1
if [[ "$CONTAINER_SHUTDOWN_CLEANUP_ENABLE" = true || "$CONTAINER_SHUTDOWN_CLEANUP_ENABLE" = 1 ]]; then
echo "Feature: Enabling shutdown cleanup against ${CONTAINER_SHUTDOWN_CLEANUP_URL:=http://localhost:3000/your/route/to/check/ok_to_shutdown}"
fi
# handle graceful shutdown, inspired by http://veithen.io/2014/11/16/sigterm-propagation.html
_onContainerEnd() {
echo ""
echo -n "OnContainerEnd Caught!"
if [[ "$CONTAINER_SHUTDOWN_CLEANUP_ENABLE" = true || "$CONTAINER_SHUTDOWN_CLEANUP_ENABLE" = 1 ]]; then
echo " Running cleanup task..."
while true; do
echo -n " cleanup task ${CONTAINER_SHUTDOWN_CLEANUP_URL} returned... "
CLEANUP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${CONTAINER_SHUTDOWN_CLEANUP_URL})
# if the script 404s, we also exit as we'll never be able to cleanup
if [[ "$CLEANUP_STATUS" == 404 || "$CLEANUP_STATUS" == 500 || "$CLEANUP_STATUS" == 200 ]]; then
echo "$CLEANUP_STATUS, exiting!"
break
else
echo "$CLEANUP_STATUS, waiting."
sleep 5
fi
done
else
echo " Shutting down without cleanup task..."
fi
kill -TERM ${PID} 2>/dev/null
EXIT_STATUS=$?
exit ${EXIT_STATUS};
}
trap _onContainerEnd TERM INT
# don't use exec here as it executes a command that completely replaces the current process.
# The current shell process is destroyed, and entirely replaced by the command you specify, so we can't track/wait on it
# instead, use & to start it in the background while this script continues to run at the wait command
/usr/local/lib/build/run.sh &
PID=$!
wait ${PID}
@ghidinelli
Copy link
Author

This docker entrypoint function creates an onContainerEnd event we can use to run graceful shutdown tasks before allowing our container to exit. We use this on AWS Fargate ECS to ensure that any email temporarily spooled to disk is allowed to finish sending before the task is killed.

In our case, we call a URL inside the container, but you could replace that with any URL or with any other code.

Replace the /usr/local/lib/build/run.sh with whatever actual executable you want to run in your container (e.g. node, java, python, go, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment