Reverse Proxy
A reverse proxy terminates TLS and forwards requests to Presswerk and Keycloak. Both services need their own domain or subdomain.
| Service | Internal | External (example) |
|---|---|---|
| Application | http://localhost:8080 | https://reports.your-domain.com |
| Keycloak | http://localhost:8081 | https://auth.your-domain.com |
Keycloak is already configured with KC_PROXY_HEADERS=xforwarded to trust X-Forwarded-* headers.
server { listen 443 ssl http2; server_name reports.your-domain.com;
ssl_certificate /etc/ssl/certs/your-cert.pem; ssl_certificate_key /etc/ssl/private/your-key.pem;
client_max_body_size 50m;
location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}
server { listen 443 ssl http2; server_name auth.your-domain.com;
ssl_certificate /etc/ssl/certs/your-cert.pem; ssl_certificate_key /etc/ssl/private/your-key.pem;
location / { proxy_pass http://localhost:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}
# HTTP → HTTPS redirectserver { listen 80; server_name reports.your-domain.com auth.your-domain.com; return 301 https://$host$request_uri;}Traefik
Section titled “Traefik”Add Traefik as a Docker service and label the application containers:
services: traefik: image: traefik:v3 command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.letsencrypt.acme.email=admin@your-domain.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt_data:/letsencrypt
app: labels: - "traefik.enable=true" - "traefik.http.routers.app.rule=Host(`reports.your-domain.com`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.tls.certresolver=letsencrypt" - "traefik.http.services.app.loadbalancer.server.port=8080"
keycloak: labels: - "traefik.enable=true" - "traefik.http.routers.keycloak.rule=Host(`auth.your-domain.com`)" - "traefik.http.routers.keycloak.entrypoints=websecure" - "traefik.http.routers.keycloak.tls.certresolver=letsencrypt" - "traefik.http.services.keycloak.loadbalancer.server.port=8080"reports.your-domain.com { reverse_proxy localhost:8080}
auth.your-domain.com { reverse_proxy localhost:8081}Caddy handles TLS automatically with Let’s Encrypt.
HAProxy
Section titled “HAProxy”frontend https bind *:443 ssl crt /etc/haproxy/certs/ mode http
acl is_app hdr(host) -i reports.your-domain.com acl is_auth hdr(host) -i auth.your-domain.com
use_backend app if is_app use_backend keycloak if is_auth
backend app mode http option forwardfor http-request set-header X-Forwarded-Proto https server presswerk 127.0.0.1:8080 check
backend keycloak mode http option forwardfor http-request set-header X-Forwarded-Proto https server keycloak 127.0.0.1:8081 checkImportant Headers
Section titled “Important Headers”The following headers must be forwarded for Keycloak and Presswerk to work correctly behind a proxy:
| Header | Required By | Purpose |
|---|---|---|
Host | Both | Original hostname for URL generation |
X-Forwarded-For | Both | Client IP address |
X-Forwarded-Proto | Both | Original protocol (http/https) |
X-Real-IP | Application | Client IP for logging |