Production-ready crystal application in docker must process correctly several
signals to shutdown properly. There is two commands in docker can be used to stop running container: docker stop
and docker kill
. First one, docker stop
stops a running container by sending it SIGTERM signal, let the main process process it, and after a grace period uses SIGKILL to terminate the application.
In this article I’ll show how to process SIGING (Ctrl-C), SIGTERM and SIGKILL with Crystal-lang.
Download
It’s a part of my sandbox repository, download it here.
Not familiar with crystal-lang? This is the main file with business logic.
Installation
Everything is dockerised, just get docker installed and download git repository.
Usage
For development-mode application run this:
docker build --pull --force-rm \
-t crystal-signal-trap \
--file ./Dockerfile . \
&& docker run -ti --rm --name=trap crystal-signal-trap
But most important is to get signals trap working in production-ready docker, which is scratch, busybox or alpine-based. To test it, run following snippet:
docker build --pull --force-rm \
-t crystal-signal-trap \
--file ./Dockerfile-production . \
&& docker run -ti --rm --name=trap crystal-signal-trap
Demo
I want to process signals separately!
Instead of grouping signals trap as it’s made in the demo app, it is possible just to process any of them:
Signal::INT.trap do
# Processing SIGING
end
More signals?
It is possible to send other signals with docker:
docker kill --signal=SIGHUP my_container
In this case, Crystal-lang app shall catch that signal: Signal::INT.trap { ... }
. Here is the list of known by Crystal-lang signals.
References: