diff --git a/playbooks/roles/haproxy/files/docker/docker-compose.yaml b/playbooks/roles/haproxy/files/docker/docker-compose.yaml
index dab8446f1c..e8a699c218 100644
--- a/playbooks/roles/haproxy/files/docker/docker-compose.yaml
+++ b/playbooks/roles/haproxy/files/docker/docker-compose.yaml
@@ -5,7 +5,34 @@ version: '2'
 services:
   haproxy:
     restart: always
-    image: docker.io/library/haproxy:2.3
+    image: docker.io/library/haproxy:latest
+    # NOTE(ianw) 2021-05-17 : haproxy >= 2.4 runs as a non-privileged
+    # user.  The main problem here is we use host networking, so the
+    # haproxy user is not allowed to bind to low ports (80/443).  The
+    # secondary problem permissions to disk files/socket.
+    #
+    # As of this writing, non-host ipv6 networking is a big PITA.  You
+    # give docker a range in "fixed-cidr-v6"; the first problem is
+    # figuring out your routable prefix our hetrogenous environments
+    # and getting the daemon setup.  The second problem is making sure
+    # that range actually passes packets.  Insert hand-wavy things
+    # that range from setting up routes, to NDP proxies, etc.  Then we
+    # have the problem that docker then assigns containers addresses
+    # randomly out of that (no good for DNS) which requires more
+    # setup.
+    #
+    # Now we could override security policies and set
+    # /proc/sys/net/ipv4/ip_unprivileged_port_start to 0 to allow
+    # anyone to bind to low ports.  That doesn't seem right.
+    #
+    # ip6tables NAT is another option here, which is still
+    # experimental in docker 20.10.6.  In theory, this works well for
+    # our use-case where unprivileged containers bind to high ports
+    # and we just want packets that reach external 80/443/8125 ports
+    # to get into their containers and out again.
+    #
+    # Until this is sorted, run as root
+    user: "root:root"
     network_mode: host
     volumes:
       - /dev/log:/dev/log