Skip to main content

ECS Task healtheck for Alpine-based containers

· 3 min read
Akhan Zhakiyanov
Lead engineer

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,
},
...
},
...
})