Traefik Setup
Expose uses Traefik as a reverse proxy for TLS termination and routing. This guide covers setting up Traefik for use with Expose.
Why Traefik?
- Automatic TLS certificate management with Let’s Encrypt
- Docker-native service discovery
- Wildcard certificate support via DNS challenge
- WebSocket support out of the box
Directory Structure
/opt/traefik/├── docker-compose.yml├── traefik.yml└── letsencrypt/ └── acme.jsonConfiguration Files
traefik.yml
# API and Dashboardapi: dashboard: true insecure: false
# Entry pointsentryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443"
# Certificate resolverscertificatesResolvers: letsencrypt: acme: email: your@email.com storage: /letsencrypt/acme.json dnsChallenge: provider: ovh # Your DNS provider delayBeforeCheck: 30 resolvers: - "1.1.1.1:53" - "8.8.8.8:53"
# Docker providerproviders: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: webdocker-compose.yml
services: traefik: image: traefik:v3.0 container_name: traefik restart: always ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik.yml:/etc/traefik/traefik.yml:ro - ./letsencrypt:/letsencrypt environment: # OVH credentials (change for your provider) - OVH_ENDPOINT=ovh-eu - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY} - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET} - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY} networks: - web labels: - "traefik.enable=true" # Dashboard (optional) - "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.com`)" - "traefik.http.routers.dashboard.entrypoints=websecure" - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xxx"
networks: web: external: trueDNS Provider Configuration
OVH
environment: - OVH_ENDPOINT=ovh-eu - OVH_APPLICATION_KEY=xxx - OVH_APPLICATION_SECRET=xxx - OVH_CONSUMER_KEY=xxxCloudflare
environment: - CF_API_EMAIL=your@email.com - CF_DNS_API_TOKEN=xxxDigitalOcean
environment: - DO_AUTH_TOKEN=xxxSee Traefik DNS Providers for more options.
Starting Traefik
# Create networkdocker network create web
# Create acme.json with correct permissionsmkdir -p letsencrypttouch letsencrypt/acme.jsonchmod 600 letsencrypt/acme.json
# Start Traefikdocker compose up -d
# Check logsdocker logs -f traefikVerifying Setup
# Check Traefik is runningdocker ps | grep traefik
# Test certificate generation (wait a few minutes)curl -v https://api.yourdomain.comTroubleshooting
Certificate Not Generated
- Check DNS is propagated:
dig +short api.yourdomain.com - Check Traefik logs:
docker logs traefik | grep -i acme - Verify DNS API credentials
- Ensure acme.json permissions are 600
502 Bad Gateway
- Check the backend service is running
- Verify network connectivity
- Check service labels are correct
WebSocket Issues
Ensure the backend service has proper WebSocket headers in Traefik labels if needed:
labels: - "traefik.http.services.myservice.loadbalancer.server.scheme=ws"