dockerhaproxy

How do I reload haproxy.cfg on the default Dockerfile?


I'm using the default HAProxy Docker image from https://github.com/dockerfile/haproxy

Unfortunately I can't get it to reload my config properly.

If I run

$ sudo docker exec haprox haproxy -f /etc/haproxy/haproxy.cfg -p '$(</var/run/haproxy.pid)' -st '$(</var/run/haproxy.pid)'

it just dumps out the help file. If I run

$ sudo docker exec haprox 'haproxy -f /etc/haproxy/haproxy.cfg -p $(</var/run/haproxy.pid) -st $(</var/run/haproxy.pid)'

I get

2014/12/30 00:03:23 docker-exec: failed to exec: exec: "haproxy -f /etc/haproxy/haproxy.cfg -p $(</var/run/haproxy.pid) -st $(</var/run/haproxy.pid)": stat haproxy -f /etc/haproxy/haproxy.cfg -p $(</var/run/haproxy.pid) -st $(</var/run/haproxy.pid): no such file or directory

Boo. None of those things are what I want. I can run docker exec haprox service haproxy reload - but this ends out spawning several haproxy processes, so when I connect via the unix socket I get one set of information from show stat but I get an entirely different set of information from the http stats page.

I'm trying to set it up so that I can do graceful redeploys of our legacy software, but it does very very bad things with Tomcat sessions, so my only option is to keep existing sessions alive and pinging the same server.

backend legacy
    cookie SERVERID insert indirect preserve
    server A 123.0.0.123:8080 cookie A check
    server B 123.0.0.123:8080 cookie B check

does the trick. I can call up the socket and run set weight legacy/A 0 and it will drain connections from server A.

But (remember that legacy part?) I have to bop my server A/B containers on the head and bring up new ones. I've got my system setup where I'm generating the new config just fine, but when I reload... strange things happen.

As mentioned earlier, it ends out spawning several haproxy processes. I get different information from the stats page and the unix socket. It also appears that the pid file of the process that I'm communicating with in the browser vs. socat are different.

Worst of all, though, is that it will stop http connections with a 503 - and using ab to test will report some dropped connections. This part is not OK.

Old sessions MUST continue to function until the old server goes down/cookies are cleared. It seems like the rest of the Internet is able to do what I'm trying to do... What am I doing wrong here?


Solution

  • if you run ps inside the container as follows you will see the container you have linked runs haproxy as pid 1 which cannot be killed without killing the container and also it is run in foreground so without a pid file. If you want to reload run haproxy in the background in your container and make some other process such as supervisor the primary process.

    docker exec -it haproxy ps aux 
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    haproxy      1  0.0  0.2  28988  4576 ?        Ss   02:41   0:00 haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid