Skip to content

Instantly share code, notes, and snippets.

@b-turchyn
Last active February 4, 2022 18:14
Show Gist options
  • Save b-turchyn/555d893d2055e5bda3fa56ee78910d1e to your computer and use it in GitHub Desktop.
Save b-turchyn/555d893d2055e5bda3fa56ee78910d1e to your computer and use it in GitHub Desktop.
Docker Compose file for Traefik ForwardAuth Support with Keycloak
# Original blog post: https://brianturchyn.net/traefik-forwardauth-support-with-keycloak/
# In here, we define three services:
# - The Traefik proxy, which we will both feed traffic through
# and protect the dashboard via Keycloak
# - The forwardauth service, which is used as a mediator between
# Traefik and Keyclok (or your IDP of choice)
# - Keycloak, your identity provider (IDP)
#
# These were pulled from separate Docker Compose files (Keycloak
# was on its own), but should work just fine in a single file.
#
# NETWORKS:
# This file assumes that it exists in a folder named "traefik". As a result,
# you will see references to `traefik_webgateway`, which is the externally-facing
# Docker network name, but internally within the file it's named `webgateway`.
# As an example, on the `keycloak` container there is a label to denote the
# Docker network to connect over, but it references `traefik_webgateway`.
services:
proxy:
image: traefik:latest # v2.4.13 as of testing
command: --web --providers.docker --docker.domain=docker.localhost
restart: always
# Create the network we will listen on. Other containers will bridge through this.
networks:
- webgateway
# Listen for both HTTP and HTTPS requests
ports:
- '443:443'
- '80:80'
# Volumes are not relevant to the setup, but hey, good practice!
volumes:
- ./config:/etc/traefik:rw
- /var/run/docker.sock:/var/run/docker.sock
labels:
# Enable access to the Traefik dashboard, and protect it with Keycloak
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`tempest.ssh.btdev.org`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=traefik-forward-auth"
# Define a "redirect-to-HTTPS" middleware, useful for other containers
- "traefik.http.middlewares.https.redirectscheme.scheme=https"
- "traefik.http.middlewares.https.redirectscheme.permanent=true"
# TLS configuration. This is backed by logic in the config file and/or env vars as required
- "traefik.http.routers.api.tls=true"
- "traefik.http.routers.api.tls.certresolver=cloudflare"
# Going over HTTP? Force to go over HTTPS
- "traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)"
- "traefik.http.routers.http_catchall.entrypoints=web"
- "traefik.http.routers.http_catchall.middlewares=https"
forwardauth:
image: mesosphere/traefik-forward-auth
restart: always
# Put on the same network as Traefik
networks:
- webgateway
# Alternatively (and preferably), put these into an `env_file` instead.
# You may need to double-quote depending on what's in your signing secret.
environment:
- "SECRET=<my-signing-secret>"
- PROVIDER_URI=https://<my-keycloak-domain.example.com>/auth/realms/btdev
- CLIENT_ID=traefik
- CLIENT_SECRET=<my-client-secret>
# Because of issues I've run into in the past, I explicitly define my Traefik
# network and incoming port. You may not need to.
# For the forwardauth address below, this *needs* to be the same as the name of
# this service as defined above. In this case, it's `forwardauth`. Note that this
# is *not* the same as the external-facing URL to Keycloak; it's the internal
# hostname that would get defined by Docker.
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_webgateway"
- "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
- "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
- "traefik.http.routers.traefik-forward-auth.tls=true"
- "traefik.http.routers.traefik-forward-auth.tls.certresolver=cloudflare"
- "traefik.http.routers.traefik-forward-auth.rule=Path(`/_oauth`)"
- "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://forwardauth:4181"
- "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
- "traefik.http.middlewares.traefik-forward-auth.forwardauth.trustForwardHeader=true"
- "traefik.http.routers.traefik-forward-auth.middlewares=traefik-forward-auth"
keycloak:
image: jboss/keycloak
restart: always
environment:
- DB_VENDOR=postgres
- DB_ADDR=<db-server>
- DB_USER=<db-user>
- DB_PASSWORD=<db-password>
- DB_DATABASE=<db-database>
- KEYCLOAK_FRONTEND_URL=https://<my-keycloak-domain.example.com>/auth/
- PROXY_ADDRESS_FORWARDING=true
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_webgateway"
- "traefik.http.routers.keycloak.entrypoints=websecure"
- "traefik.http.routers.keycloak.tls=true"
- "traefik.http.routers.keycloak.tls.certresolver=cloudflare"
- "traefik.http.routers.keycloak.rule=Host(`<my-keycloak-domain.example.com>`)"
# I had these in my labels, but I believe these are from Traefix 1.x and not required
- "traefik.backend=basic"
- "traefik.basic.frontend.rule=Host:<my-keycloak-domain.example.com>"
networks:
- webgateway
- keycloak
networks:
webgateway:
driver: bridge
# I define separate networks for each logical service I run; Keycloak was in its own file.
keycloak:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment