Kamal 2 is coming with a brand new custom proxy that’s replacing Traefik. Let’s have a look at why is that and what it means.
Why Kamal needs a proxy
Kamal is a simple deployment tool built around Docker containers. While Docker itself has a Swarm mode allowing for more robust deploys, Kamal keeps things simple by running the containers with straightforward docker run
calls. But starting and stopping containers this way comes without their automatic replacement. Kamal needs a way to handle zero-downtime deployment for web containers so it originally incorporated Traefik.
Why Traefik
While there are many HTTP proxies around, Kamal was in the market for something of the auto-discovery of Docker containers. Something could make the proxy configuration management minimal. Traefik is such a proxy – it was specifically built as a dynamic reverse proxy for orchestrating container traffic. This meant that Kamal would only need to label the web containers for Traefik to select them. Docker health checks then did the rest by pointing to the healthy containers that should receive new traffic.
Why a new proxy
There was one problem with Traefik. Kamal had to create a special cord file on the host and bind mount it into the container to be able to control the health check that was responsible for driving traffic alongside the label. By introducing the cord file check Kamal could make any container unhealthy by deleting their associated cord file. And while it mostly worked, it was seen as a hack.
Kamal is an imperative tool and so it needs a proxy that works in a similar way. Traefik was also the most complex and misunderstood part of Kamal’s stack. So while people mostly figure things out in the end, there was an opportunity to simplify it. This is especially true when it comes to the most requested feature for Kamal – hosting multiple apps on the same system with automatic TLS certificates.
Kamal Proxy
The new Kamal proxy is simply called kamal-proxy
and it’s designed to make it easy to coordinate zero-downtime deployments with an option of issuing TLS certificates. Instead of labeling containers, we tell the proxy what kind of service to deploy with a hostname:port
target:
$ kamal-proxy deploy my-app --target web-1:3000
This reads as deploy myapp
service with web-1
hostname on port 3000
. We can reference the container like this thanks to the Docker DNS on the same network. Deploying a service like this will wait for the containers to become healthy and reroute the traffic from any previously deployed instance of the service.
But that’s not all. We can also specify a host to run more services on the same server:
$ kamal-proxy deploy first-app --target web-1:3000 --host app1.example.com
$ kamal-proxy deploy second-app --target web-2:3000 --host app2.example.com
Providing a host will ensure the ports are not in conflict.
And finally, if we need a certificate for the domain name we pass --tls
at the end:
$ kamal-proxy deploy first-app --target web-1:3000 --host app1.example.com --tls
Note that there is no specific configuration file and the proxy itself has to be running.
Kamal 2 configuration
There will be little need for you to run the proxy commands yourself as it will be done by Kamal. Here’s how it will look in the Kamal deploy/config.yml
file:
# config/deploy.yml
...
# The new proxy config
proxy:
ssl: true
host: app.example.com
The new proxy
settings have two parts. A required host
for routing on the same system and optional ssl
for automatic TLS certs.
Kamal Proxy features
To sum up the new proxy feature set:
- Routing based on provided hosts
- Automatic TLS certificates via Let’s Encrypt
- Request and response buffering
- Maximum requests and response sizes
The new proxy should also bring new features to Kamal such as pausing requests, maintenance mode and gradual rollouts.