Notes to self

A brief look at the new Kamal Proxy replacing Traefik

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.

And there was one more reason. Traefik was 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.

Check out my book
Learn how to use Kamal to deploy your web applications with Kamal Handbook. Visualize Kamal's concepts, understand Kamal's configuration, and deploy practical life examples.
by Josef Strzibny
RSS