version: "3.9" services: haproxy: # This is the official haproxy-supported container. image: "docker.io/haproxytech/haproxy-debian:2.9.6" volumes: - /opt/sunet-cdn/customers/<%= @customer %>/conf/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro - /opt/sunet-cdn/customers/<%= @customer %>/shared:/shared - /opt/sunet-cdn/customers/<%= @customer %>/certs:/certs:ro - /opt/sunet-cdn/customers/<%= @customer %>/certs-private:/certs-private:ro # The general (outdated?) advice is never to start haproxy as an # unprivileged user for production purposes: # https://docs.haproxy.org/2.9/management.html # ... but looking at https://hub.docker.com/_/haproxy it states: # === # Note: the 2.4+ versions of the container will run as USER haproxy by # default (hence the --sysctl net.ipv4.ip_unprivileged_port_start=0 above), # but older versions still default to root for compatibility reasons; use # --user haproxy (or any other UID) if you want to run as non-root in older # versions. # === # ... So it seems reasonable to use a custom user even for haproxy. The # very large uid/gid is used to have a reasonable guarantee that nothing in # the normal system will ever collide with it, and is inspired by what # the OpenShift kubernetes system does: # https://www.redhat.com/en/blog/a-guide-to-openshift-and-uids# user: <%= @customer_uid %>:<%= @customer_uid %> # Setting network_mode is done to not involve overhead of NAT, the # idea is that it is one less state table to take care of in case of # handling DDoS traffic, and it also means we will see real client IP # addresses in haproxy for setting headers etc. network_mode: "host" # The following can not be used with network_mode: host so needs to be set # in the global OS sysctl instead: # === #sysctls: # - net.ipv4.ip_unprivileged_port_start=80 # === varnish: # We build our own varnish with the slash vmod present. We use the slash # "fellow" storage backend to be able to persist cached content to disk, so # it is retained in case of a restart of the container or machine. image: "platform.sunet.se/sunet-cdn/cdn-varnish:af7f7d11e61acf9f6113811615d1baa46daf3bd1" # Use the same custom user as is used for haproxy. user: <%= @customer_uid %>:<%= @customer_uid %> volumes: - /opt/sunet-cdn/customers/<%= @customer %>/conf/varnish.vcl:/etc/varnish/varnish.vcl:ro - /opt/sunet-cdn/customers/<%= @customer %>/shared:/shared - /opt/sunet-cdn/customers/<%= @customer %>/cache:/cache # From https://www.varnish-software.com/developers/tutorials/running-varnish-docker/: # === # The /var/lib/varnish folder is frequently accessed by the varnishd # program. Loading this folder into memory and accessing it through tmpfs # would accelerate access to this folder. # === # Using the subfolder "varnishd" is an updated expectation, see # https://github.com/varnish/docker-varnish/issues/51 tmpfs: - /var/lib/varnish/varnishd:exec,uid=<%= @customer_uid %> # Varnish does not need to listen to any network ports as all communication # between it and haproxy happens over a UNIX socket. command: [ "-E", "/usr/lib/varnish/vmods/libvmod_slash.so", "-a", "/shared/varnish.sock,PROXY,mode=600", "-f", "/etc/varnish/varnish.vcl", "-p", "feature=+http2", "-s", "fellow=fellow,/cache/fellow-storage,512MB,512MB,10MB", ] # Allow io_uring operations expected by slash fellow. security_opt: - seccomp:/opt/sunet-cdn/conf/varnish-slash-seccomp.json # Fix error log: "varnish-1 | Info: Child (29) said fellow_io_uring_register_buffers: fellow_io_uring_register_buffers Cannot allocate memory (12)" ulimits: memlock: -1