Traefik is an open-source cloud-native, modern reverse proxy and edge Router that makes publishing services quite simple. Its key characteristic is that it can automatically discover the right configuration for services as it inspects infrastructure to find relevant information on which service serves which request.
In this post, we will take a look at how Apereo CAS can be deployed via Docker and sit behind Traefik. A dockerized CAS deployment is an existing CAS overlay project wrapped in Spring Boot, Docker, and Docker Compose. This setup requires a few extra modifications in order to allow an additional integration with Traefik for http and https access.
Our starting position is as follows:
The first step is to allow the CAS server to serve requests on a designated port
8080 and under
http. To do this, the
cas.properties file should be adjusted to include the following settings:
server.ssl.enabled=false server.port=8080 server.tomcat.remoteip.protocol-header-https-value=http
You can choose any port you prefer, but you do need to make sure the same port is exposed in the
Dockerfile for the CAS server via the
EXPOSE directive. Traefik retrieves the private IP and port of containers from the Docker API as part of its auto-configuration and discovery strategy.
Ports detection works as follows:
Note that the CAS
Dockerfile found in the overlay project does include
EXPOSE 8080 8443 for port exposure.
docket-compose.yml file should be adjusted to pull down the Traefik docker image and auto-configure it:
version: '3.8' services: cas: build: . labels: - "traefik.enable=true" - "traefik.http.routers.cas.rule=HOST(`auth.example.org`)" - "traefik.http.services.cas.loadbalancer.server.port=8080" traefik: image: traefik:v2.3.0 ports: - "80:80" - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - "$PWD/traefik.toml:/etc/traefik/traefik.toml"
The labels will be read later by Traefik to auto-configure the service. Specifically,
traefik.enableensures that Traefik sees our CAS container and routes traffic to it. This directive can be replaced with
exposedByDefault = truein the Traefik configuration.
casrouter rule for Traefik that allows it to route traffic to the CAS container if the host header matches
traefik.http.services.cas.loadbalancer.server.portspecifies the target destination port for traffic into the running service.
The Traefik container itself is exposed over port
80 for routing traffic and we also allow for port
8080 which grants access to the Traefik dashboard. We are also mapping two volumes:
traefik.tomlconfiguration file inside the Traefik container which is loaded by Traefik on startup.
At this point, the only remaining task is to create and design the
[entryPoints] [entryPoints.cas] address = ":80" [api] insecure = true [log] level = "INFO" [accessLog] [providers] [providers.docker] exposedByDefault = true
We can use the following to build and run our Docker containers:
docker-compose down && docker-compose up --build
Please be patient, as doing a build for the first time might take a while depending on your bandwidth. Once ready, you should be able to browse to
http://localhost:8080/dashboard and access the Traefik dashboard:
We can also examine our
CAS router and its configuration:
Of course, you should be able to get to the CAS server using
For extra credit, you can in fact examine the CAS service and its configuration that is automatically discovered and configured by Traefik to note the expected port:
Setting up TLS is quite similar to previous steps. First, we need to make sure the correct protocol header that is passed from Traefik to CAS is defined as
docker-compose.yml file must be adjusted to turn on TLS, relevant ports and map volumes and certificates:
version: '3.8' services: cas: build: . labels: - "traefik.enable=true" - "traefik.http.routers.cas.rule=HOST(`auth.example.org`)" - "traefik.http.services.cas.loadbalancer.server.port=8080" - "traefik.http.routers.cas.tls=true" traefik: image: traefik:v2.3.0 ports: - "80:80" - "443:443" - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - "$PWD/traefik.toml:/etc/traefik/traefik.toml" - "$PWD/server.crt:/etc/traefik/server.crt" - "$PWD/server.key:/etc/traefik/server.key" - "$PWD/certificates.toml:/etc/traefik/certificates.toml"
The most notable differences are,
traefik.http.routers.cas.tlslabel enables TLS for the CAS service.
443is now enabled to front HTTPS requests.
openssland Traefik also has excellent support for Let’s Encrypt and other ACME providers for automatic certificate generation.
certificates.tomlhow the above private key and certificate should be loaded by Traefik.
certificates.toml file simply points to the certificates that are mapped inside the Traefik container:
[[tls.certificates]] certFile = "/etc/traefik/server.crt" keyFile = "/etc/traefik/server.key" [tls.stores] [tls.stores.default] [tls.stores.default.defaultCertificate] certFile = "/etc/traefik/server.crt" keyFile = "/etc/traefik/server.key"
Finally, we should adjust the Traefik configuration file to enable redirection from port
443 and specify how Traefik should load our certificate configuration file:
[entryPoints] [entryPoints.cas] address = ":80" [entryPoints.cas.http] [entryPoints.cas.http.redirections] [entryPoints.cas.http.redirections.entryPoint] to = "websecure" scheme = "https" [entryPoints.websecure] address = ":443" [api] insecure = true [providers.file] filename = "/etc/traefik/certificates.toml" [log] level = "INFO" [accessLog] [providers] [providers.docker] exposedByDefault = true
If you rebuild and launch the containers again, the Traefik dashboard should indicate that port
443 is enabled to serve secure traffic:
Of course, our router setup also should indicate that TLS is now activated:
At this point, you should be able to get to the CAS server using
I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please know that all other use cases, scenarios, features, and theories certainly are possible as well. Feel free to engage and contribute as best as you can.