Load-balancing HTTP and WebSocket channels with Docker in AWS
With the addition of WebSocket channels in Zato 3.0, a question arises of how to combine both HTTP and WebSocket channels in Zato environments. This article shows how a Docker container running in AWS can be configured to expose a single port to handle both kind of requests, including health-status checks from Amazon’s ALB (Application Load Balancer).
Configuration
The configuration we would like to arrive at is in the diagram below:

- There is ALB (Application Load Balancer) which sends HTTP pings to Zato, expecting an HTTP 200 OK response if everything is fine
- There are WebSocket-based clients (WSX) that send their own business requests, independent of regular HTTP ones
- A Docker container holds a Zato environment, publishing port 11224 to the outside world, to ALB and WSX
- Inside the container, Zato’s load-balancer, based on HAProxy, distributes requests individual TCP sockets of a Zato server
- If the request begins with a well-known prefix (here, /ws), it is forwarded to a WebSocket channel on port 48902
- All other requests, including the one from ALB, will go the default HTTP port at 17010
WebSocket channel
First step is to ensure that a WebSocket channel’s path begins with the desired prefix, such as /ws, as in the screenshot.

HAProxy
Now, HAProxy needs to be reconfigured in its source code view, from web-admin:

-
The changes required need to go the stanza called ‘front_http_plain’ - right after its current content add the lines with logic that will separate incoming requests into WebSocket ones or any other.
-
Next, add a new HAProxy backend pointing to the WebSocket channel created earlier.
-
Now, stop and start the load-balancer again
# ############################################################################## frontend front_http_plain ... acl is_websocket path_beg /ws acl is_websocket hdr(Upgrade) -i WebSocket use_backend websockets if is_websocket # ############################################################################## backend websockets mode http option http-server-close option forceclose server http_plain--server1 127.0.0.1:48902 check inter 2s rise 2 fall 2 # ##############################################################################
That’s it
There are no more steps as far Zato is concerned - if a Docker container is now started with port 11224 mapped to 11223 inside the container, all the external applications will be able to access Zato-based services using both HTTP and WebSockets through a single port:
$ docker run -p 11224:11223 zato