ECS Task healtheck for Alpine-based containers
If you are working with AWS ECS, you might know about ECS task healthcheck.
AWS documentation suggests to use curl
in command:
[ "CMD-SHELL", "curl -f http://localhost/ || exit 1" ]
I usually try to minimize container image size, thus my first choice for base image is Alpine.
Unfortunately, it doesn't come with curl installed out of the box. It only includes wget.
AWS example command analysis
Let's analyze how healthcheck command works and what it does
curl part
According to curl manpage -f
flag let's us fail silently (no output at all) on HTTP errors
-f, --fail
(HTTP) Fail fast with no output at all on server errors. In normal cases when an HTTP server fails to deliver a document, it returns an HTML document stating so (which often also describes why and more). This flag will prevent curl from outputting that and return error 22.
Double pipe || operator
A double pipe (||) causes the following command to be executed only if the preceding command returned an exit status of non-zero.
Exit 1
Returning non-zero code means error happened, which will cause container to stop.
So if curl command failed and returned code 22, exit 1 will be executed setting ECS Task status to UNHEALTHY
Healthcheck command with wget
Let's apply same logic but with what wget offers us.
Retries
Apparently by default wget will retry, which we don't need in this case. So we set number of retries to 1
--tries=number
Set number of retries to number. Specify 0 or inf for infinite retrying. The default is to retry 20 times, with the exception of fatal errors like "connection refused" or "not found" (404), which are not retried.
Spider-mode
--spider
When invoked with this option, Wget will behave as a Web spider, which means that it will not download the pages, just check that they are there
This one is actually optional, but some people may consider healthcheck without downloading document.
No-verbose
--no-verbose
Turn off verbose without being completely quiet (use -q for that), which means that error messages and basic information still get printed.
We might need error information to be printed, so let's include this too.
So wget healthcheck command equivalent will be:
[ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost || exit 1" ]
Pulumi example
new awsx.ecs.FargateService('alpine-service', {
taskDefinition: new awsx.ecs.FargateTaskDefinition(`${kernelServiceName}-task-definition`, {
container: {
image: 'some-alpine-based-image',
healthCheck: {
command: ['CMD-SHELL', 'wget --no-verbose --tries=1 --spider http://localhost || exit 1'],
interval: 30,
retries: 3,
timeout: 5,
},
...
},
...
})