Container - HAProxy
HAProxy is a high-performance reverse proxy and load balancer as a Container.
For optimal security, it is highly recommended to use a reverse HTTP/HTTPS proxy like HAProxy as an intermediary between external users and your internal services, rather than exposing containers directly to the network.
Configuration
To set up a HAProxy Container on your RouterOS device, follow these steps below.
Make sure you have created a Container network before proceeding.
-
Create HAProxy Container mount points.
/container/mounts/add list=haproxy_etc src=disk1/haproxy-etc dst=/usr/local/etc/haproxy -
Create a HAProxy Container.
/container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/haproxy mountlists=haproxy_etc user=0:0 name=haproxy -
Connect to your RouterOS device using an SFTP client (for example, WinSCP when using Microsoft Windows) and create a new file
disk1/haproxy-etc/haproxy.cfg, you can use the following config as an example.defaultsmode httptimeout client 10stimeout connect 10stimeout server 10stimeout http-request 10sfrontend http_synapsebind *:80use_backend synapsebackend synapseserver server1 172.17.0.2:8008 maxconn 32 -
Start the HAProxy Container.
/container/start [find where name=haproxy]
Advanced: HAProxy with Certbot
This example shows how to configure HAProxy to serve HTTPS traffic and automatically renew the certificates by using Certbot and RFC2136.
-
Create HAProxy Container:
/container/mounts/add list=MOUNT_HAPROXY src=disk1/volumes/haproxy/config dst=/usr/local/etc/haproxy/container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/images/haproxy mountlists=MOUNT_HAPROXY name=haproxy start-on-boot=yes user=0:0 logging=yes -
Create a new file called
haproxy.cfgon your PC and upload it todisk1/volumes/haproxy/config/, adjust the configuration to your needs:globallog stdout format raw local0 infostats socket :9999 level admin expose-fd listenersssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCMssl-default-server-ciphers EECDH+AESGCM:EDH+AESGCMssl-default-bind-options ssl-min-ver TLSv1.2ssl-default-server-options ssl-min-ver TLSv1.2tune.ssl.default-dh-param 2048tune.bufsize 43768tune.ssl.cachesize 1000000nbthread 8defaultslog globaltimeout client 10stimeout connect 10stimeout server 10stimeout http-request 10sfrontend frontend_webappmode httpoption httplogoption http-server-closeoption forwardfor except 127.0.0.0/8stick-table size 100k expire 30s store http_req_rate(10s)http-request track-sc0 srchttp-request deny deny_status 429 if { sc_http_req_rate(0) gt 10000 }bind *:80bind *:443 ssl crt /usr/local/etc/haproxy/certs/http-request redirect scheme https unless { ssl_fc }http-request set-header X-Forwarded-Host %[req.hdr(host)]http-request set-header X-Forwarded-For %[src]use_backend backend_webappbackend backend_webappmode httpbalance roundrobinoption http-server-closeoption forwardforserver server1 172.17.0.2:8080 -
Create the Certbot Container:
/container/mounts/add list=MOUNT_CERTBOT_CONFIG src=disk1/volumes/certbot/config dst=/etc/letsencrypt/container/mounts/add list=MOUNT_CERTBOT_DATA src=disk1/volumes/certbot/data dst=/var/lib/letsencrypt/container/mounts/add list=MOUNT_CERTBOT_LOG src=disk1/volumes/certbot/log dst=/var/log/letsencrypt/container/mounts/add list=MOUNT_CERTBOT_HAPROXY src=disk1/volumes/haproxy/config dst=/etc/haproxy/container/add remote-image=certbot/dns-rfc2136 cmd="certonly -n --agree-tos ---rfc2136 ---rfc2136-credentials /etc/letsencrypt/rfc2136.ini -m admin@<FQDN> --deploy-hook 'cat /etc/letsencrypt/li\ve/<FQDN>/fullchain.pem /etc/letsencrypt/live/<FQDN>/privkey.pem | tee /etc/haproxy/certs/<FQDN>.pem > /dev/null; echo -e \"set ssl cert /usr/local/e\tc/haproxy/certs/<FQDN>.pem <<\\n\$(cat /etc/haproxy/certs/<FQDN>.pem)\\n\" | nc 127.0.0.1:9999; echo \"commit ssl cert /usr/local/etc/haproxy/certs/<FQDN>.pem\" | nc 127.0.0.1:9999' -d <FQDN> --cert-name <FQDN>" \interface=veth1 logging=yes mountlists=MOUNT_CERTBOT_CONFIG,MOUNT_CERTBOT_DATA,MOUNT_CERTBOT_LOG,MOUNT_CERTBOT_HAPROXY name=certbot root-dir=\disk1/images/certbot start-on-boot=yes workdir=/opt/certbot
Make sure to replace all <FQDN> placeholders in the example above with your fully qualified domain name!
-
Wait for the Container image to be downloaded and start the Certbot Container:
/container/start [find where name=certbot] -
Check the logs to make sure you successfully received a new certificate:
/log/print follow -
Start HAProxy Container:
/container/start [find where name=haproxy] -
Set up a schedule, for example, each day at 06:30 to check for a new certificate:
/system/scheduleradd interval=1d name=SCHEDULE_RenewCertbot on-event=SCRIPT_RenewCertbot policy=ftp,reboot,read,write,,test,password,sniff,sensitive,romon start-date=\2025-03-10 start-time=06:30:00/system/scriptadd dont-require-permissions=no name=SCRIPT_RenewCertbot owner=admin policy=ftp,reboot,read,write,,test,password,sniff,sensitive,romon source=\"/container/start [find where name=\"certbot\"]" -
Done
The certificate will automatically renew and replace old certificates in HAProxy without needing to restart the Container.