sajad torkamani

⚠️ Please note: These notes are for myself only as it assumes a lot of things that are tailored to my setup and which aren’t made explicit. Please find a better guide in case you come across this page.

Suppose you want to set up HTTPS for a web application you’re serving via Traefik. For simplicity, let’s assume you’re using Docker Compose in production. Here’s how you can go about it.

Create a separate docker-compose.prod.yml file for the production version of Traefik

Suppose you have this docker-compose.yml file in your Git repo that provides the Traefik Docker service for your development environment:

services:
  traefik:
    image: traefik:3.5
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--providers.file.filename=etc/traefik/dynamic.yml"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik/certs:/etc/traefik/certs
      - ./traefik/traefik.yml:/etc/traefik.yml:ro
      - ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro
    networks:
      - cpad-dev

networks:
  cpad-dev:
    external: true

For production, you’ll want a slightly different version of that config so create a separate docker-compose.prod.yml file:

services:
  traefik:
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--providers.file.filename=etc/traefik/dynamic.yml"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=sajad@hey.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik/certs:/etc/traefik/certs
      - ./traefik/traefik.yml:/etc/traefik.yml:ro
      - ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro
      - letsencrypt:/letsencrypt

volumes:
  letsencrypt:

When starting Docker Compose in production, run the below to ensure your production config is used:

docker compose up -f docker-compose.prod.yml -d

The main difference between the dev and production configs is the below:

You can read the docs here to better understand what those labels do.

Configure the application to use your resolver

In the Docker Compose file for your production application service, you’ll want something like this:

services:
  php:
    labels:
      - traefik.enable=true
      - traefik.http.routers.cpad-api.entrypoints=web
      - traefik.http.routers.cpad-api.entrypoints=websecure
      - traefik.http.routers.cpad-api.tls=true
      - traefik.http.routers.cpad-api.rule=HOST(`api.cpad.app`)
      - traefik.http.routers.cpad-api.middlewares=redirect-to-https
      - traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
      - traefik.http.services.cpad-api.loadbalancer.server.port=8080
      - traefik.http.routers.cpad-api.tls.certresolver=myresolver

The key Traefik label to enable HTTPs via Traefik is that last line:

- traefik.http.routers.cpad-api.tls.certresolver=myresolver

Links