Planted on 09 Sep 2024
Last tended on 09 Sep 2024
Kamal, developed by 37signals, is a flexible tool for automating Docker deployments and streamlining the process. One of its key features is ensuring zero-downtime deployments. To achieve this, Kamal uses Traefik as a reverse proxy to route traffic to the correct container. Traefik is a popular reverse proxy that can automatically discover new containers and create routing rules for them. This makes it easy to manage and scale applications in a dynamic environment like Docker.
By default, Kamal configures Traefik to listen on port 80 only. To enable HTTPS, you need to configure Traefik to handle SSL/TLS termination or use a separate load balancer in front of it. While these are common setups, they can be tricky to implement if you’re not familiar with Traefik’s configuration, especially when using custom certificates such as self-signed ones or Cloudflare origin server certificates.
While the configuration is not complicated, it’s beneficial to understand how Traefik works before we guide you through the process of setting it up with a custom certificate.
We’re keeping things simple here, so we skipped advanced features like providers and middlewares. Don’t worry – you don’t need them for this setup.
The first step is to define an entrypoint for HTTPS traffic. This can be achieved by adding the following configuration to Kamal:
traefik:
options:
publish:
- "443:443"
args:
entryPoints.web.address: ":80"
entryPoints.websecure.address: ":443"
entrypoints.websecure.http.tls: true
This configuration tells Traefik to recognize that port 443 is designated for handling HTTPS requests. However, it will use an automatically generated default certificate to handle HTTPS requests. Next, we need to configure Traefik to use our custom certificate.
Before updating the Traefik configuration:
Update the deploy configuration as follows:
traefik:
options:
publish:
- "443:443"
volume:
- "/var/local/certs:/var/local/certs:ro"
args:
entryPoints.web.address: ":80"
entryPoints.websecure.address: ":443"
entrypoints.websecure.http.tls: true
Traefik’s configuration is split into static and dynamic types:
Create a dynamic configuration file (dynamic.yml
) with the following content:
tls:
certificates:
- certFile: /var/local/certs/example.com.pem
keyFile: /var/local/certs/example.com.key
In the configuration file, simply list the certificate and key files. There’s no need to specify which domain names correspond to which certificates. Traefik automatically matches certificates to domain names using the SNI (Server Name Indication) header from incoming requests.
Then, use labels to tell Traefik to use the configuration in dynamic.yml
. The updated Traefik configuration should look like this:
traefik:
options:
publish:
- "443:443"
volume:
- "/var/local/traefik:/var/local/traefik:ro"
- "/var/local/certs:/var/local/certs:ro"
args:
entryPoints.web.address: ":80"
entryPoints.websecure.address: ":443"
entrypoints.websecure.http.tls: true
providers.file.filename: "/var/local/traefik/dynamic.yml"
After making these configuration changes, you must re-create the Traefik container for the new settings to take effect. Execute the following command:
kamal traefik reboot
This command will reboot stop container, remove container, start new container with new configuration.
Now that Traefik knows how to handle HTTPS requests and select the correct SSL certificate, we need to add a routing rule to the web server:
servers:
web:
hosts:
- 127.0.0.1
labels:
traefik.http.routers.app_secure.entrypoints: websecure
traefik.http.routers.app_secure.rule: Host(`example.com`)
After making these configuration changes, you need to apply them for the new settings to take effect. Execute the following commands:
kamal deploy
With these steps completed, Traefik can now handle HTTPS requests, use the Origin Server Certificate, and route requests to the web server. You can set the SSL setting in Cloudflare to Full or Full (strict).
Happy deploying!