22 ธันวาคม 2568

traefix wildcard SSL with muli provider

docker-compose.yml
services:
  traefik:
    image: traefik:v3.6
    container_name: traefik-test
    restart: unless-stopped
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - CF_DNS_API_TOKEN=${CLOUDFLARE_TOKEN}
      - SPACESHIP_API_KEY=${SPACESHIP_API_KEY}
      - SPACESHIP_API_SECRET=${SPACESHIP_API_SECRET}
    volumes:
      - ./traefik:/etc/traefik:ro
      - ./letsencrypt:/letsencrypt
    command:
      - --configFile=/etc/traefik/traefik_config.yml

  php-apache:
    image: php:8.4-apache
    container_name: php-apache-test
    restart: unless-stopped
    networks:
      - traefik_net
    volumes:
      - ./php-src:/var/www/html

networks:
  traefik_net:
    driver: bridge


traefik_config.yml
entryPoints:
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: cloudflare-resolver
        domains:
          - main: "domain1.com"
            sans:
              - "*.domain1.com"

providers:
  file:
    filename: "/etc/traefik/dynamic_conf.yml"
    watch: true

certificatesResolvers:
  cloudflare-resolver:
    acme:
      email: your-email@example.com
      storage: /etc/traefik/acme-cloudflare.json
      dnsChallenge:
        provider: cloudflare

  spaceship-resolver:
    acme:
      email: your-email@example.com
      storage: /etc/traefik/acme-spaceship.json
      dnsChallenge:
        provider: spaceship # New in lego/traefik 2025


dynamic_config.yml
http:
  routers:
    # --- CLOUDFLARE DOMAIN (Inherits from Entrypoint) ---
    router1:
      rule: "Host(`app1.domain1.com`)"
      entryPoints: ["websecure"]
      service: "service1"
      tls: {} # Uses cloudflare-resolver & wildcard automatically

    router2:
      rule: "Host(`app2.domain1.com`)"
      entryPoints: ["websecure"]
      service: "service2"
      tls: {} # Uses cloudflare-resolver & wildcard automatically

    # --- SPACESHIP DOMAIN (Manual Override) ---
    router3:
      rule: "Host(`app3.domain2.com`)"
      entryPoints: ["websecure"]
      service: "service3"
      tls:
        certResolver: "spaceship-resolver"
        domains:
          - main: "domain2.com"
            sans: ["*.domain2.com"] # Triggers wildcard issuance

    router4:
      rule: "Host(`app4.domain2.com`)"
      entryPoints: ["websecure"]
      service: "service4"
      tls:
        certResolver: "spaceship-resolver"
        # No domains block needed! It reuses the cert from Router 3
        
  services:
    service1:
      loadBalancer:
        servers: [{ url: "http://172.18.0.11:80" }]
    service2:
      loadBalancer:
        servers: [{ url: "http://172.18.0.12:80" }]
    service3:
      loadBalancer:
        servers: [{ url: "http://172.18.0.13:80" }]
    service4:
      loadBalancer:
        servers: [{ url: "http://172.18.0.14:80" }]