June 28, 2022

ACME TLS for localhost with traefik and smallstep

If you’re using docker for your local development environment and need to develop against TLS-secured endpoints (which you should as you need to run it in production anyway), you just can leverage traefik with smallstep. In this example, we just use docker as configuration provider by setting labels to container exposed via traefik. The important things are commented inline.

---
version: '3.8'
services:
  step-ca:
    image: smallstep/step-ca:0.24.2
    volumes:
      - step-ca:/home/step # shared volume between step-ca and traefik to access root ca
    environment:
      DOCKER_STEPCA_INIT_NAME: "Step CA"
      DOCKER_STEPCA_INIT_DNS_NAMES: "localhost,step-ca" # must at least include name of step-ca service which is referenced as acme.caserver
      DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT: "true"
      DOCKER_STEPCA_INIT_ACME: "true" # initialize acme provider
    networks:
      - traefik
  traefik:
    depends_on:
      - step-ca
    image: traefik:2.10
    command:
      - '--providers.docker=true'
      - '--providers.docker.network=traefik'
      - '--providers.docker.exposedByDefault=false'
      - '--api.dashboard=true'
      - '--api.insecure=true'
      - '--accesslog=true'
      - '--pilot.dashboard=false'
      - '--entryPoints.web.address=:80'
      - '--entryPoints.web.http.redirections.entryPoint.to=websecure'
      - '--entrypoints.web.http.redirections.entryPoint.scheme=https'
      - '--entrypoints.web.http.redirections.entrypoint.permanent=true'
      - '--entryPoints.websecure.address=:443' # enable secure endpoint
      - '--entrypoints.websecure.http.tls.certResolver=step-ca' # use step-ca as certresolver
      - '--certificatesresolvers.step-ca.acme.caserver=https://step-ca:9000/acme/acme/directory' # step-ca acme endpoint
      - '--certificatesresolvers.step-ca.acme.email=traefik@localhost.localdomain'
      - '--certificatesresolvers.step-ca.acme.tlsChallenge=true' # enable tls-alpn-01 challenge
    environment:
      LEGO_CA_CERTIFICATES: /home/step/certs/root_ca.crt # use root ca created by step-ca
    networks:
      - traefik
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host
    volumes:
      - step-ca:/home/step # shared volume between step-ca and traefik to access root ca
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      traefik.enable: true
      traefik.http.routers.traefik-https.rule: Host(`traefik.localhost`)
      traefik.http.routers.traefik-https.entrypoints: websecure
      traefik.http.routers.traefik-https.service: api@internal
networks:
  traefik: {}
volumes:
  step-ca: {}