HAProxy image comes with a really compact debian version, without ping, wget, curl or other commands to verify. How to use docker-compose health check for it, verifying that the HAProxy is up and running?
3 Answers
Something like this may work:
echo "" > /dev/tcp/${HOSTNAME}/${PORT} || exit 1
which is using the /dev/tcp built-in with bash to test a connection to a port you know HAProxy should be running on, and will fail if cannot connect.

- 75
- 1
- 6
-
Just to add, you may have to run it within `bash` as the container's default shell is `sh`: `bash -c "echo '' > /dev/tcp/${HOSTNAME}/${PORT}"` – garethTheRed Jun 20 '23 at 06:22
You would configure a health check in the haproxy.cfg which you pass to the docker container. The health check portion could look like:
frontend frontend_name
...
use_backend healthcheck if { path_beg /health }
backend healthcheck
server disabled-server 127.0.0.1:1 disabled
errorfile 503 /path/to/template.html
And the health check template file:
HTTP/1.0 200 OK
Cache-Control: no-cache
Connection: close
Content-Type: text/plain
up
How this works is that the health check backend, which you would route to from a frontend on whatever path you like /health for example. And instead of responding with a 503, the error file directive allows you to return a custom error response, in this case a 200.

- 443
- 2
- 10
-
Thank you, @jmoney Just some questions: 1. Which is the format of the template file? 2. Where to set the /health path? – Julia Bel Dec 11 '18 at 10:15
-
-
1. Updated the answer, it's html. 2. in the `frontend` section you'd add a `use_backend hhealthcheck if { path_beg /health }` 3. Where are you trying to call the health url from? Another docker container? You could run one with curl on it, or call your haproxy health check from somewhere else? – jmoney Dec 11 '18 at 14:00
-
3. I am using docker-compose and this won't work, because the image doesn't contain curl, for example: healthcheck: test: curl --fail -s http://localhost:
/healthcheck || exit 1 interval: 1m30s timeout: 10s retries: 3 – Julia Bel Dec 11 '18 at 15:55 -
Right, I'm not suggesting you run curl from your haproxy server, but rather from somewhere external to the container. – jmoney Dec 11 '18 at 16:20
-
Or, if you're set on running it from the docker container, you could run commands via docker compose to install curl on the haproxy container. Something like this https://stackoverflow.com/questions/30063907/using-docker-compose-how-to-execute-multiple-commands – jmoney Dec 11 '18 at 16:22
-
Afaik you cannot return other codes than the one you are catching in haproxy. If you catch 503 then you can only return a 503 template. – The Fool Feb 28 '21 at 20:13
Expanding on @AdrianF's answer above, I used the following:
In HAProxy's config, I added:
frontend health
mode http
bind 127.0.0.1:80
http-request return status 200 if { src 127.0.0.0/8 }
Then, in the Compose file for HAProxy:
healthcheck:
test: |
bash -c 'exec 3<>/dev/tcp/127.0.0.1/80; echo -e "GET / HTTP/1.1\nConnection: close\n" >&3; cat <&3 | grep -q "200 OK"'
Note: I had to use a heredoc here as a single line variant kept complaining of a YAML error, which I traced down to the colon after Connection
. There may be a way to escape that, but I couldn't figure it out.

- 1,997
- 13
- 20