1

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?

Julia Bel
  • 337
  • 4
  • 18

3 Answers3

2

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.

AdrianF
  • 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
1

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.

jmoney
  • 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
  • Also, how to call this URL, with no curl, for exemple? – Julia Bel Dec 11 '18 at 10:52
  • 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
0

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.

garethTheRed
  • 1,997
  • 13
  • 20