Traefik/Portainer/Docker wildcard SSL

Hi All,

New to the traefik world and had it setup and working as intended, however my wildcard SSL that i was using has expired, since its expiration I have tried replacing it in portainer (i set it up as a secret in portainer) however it doesnt work.

How can I go about troubleshooting this one? It seems as though the Traefik container doesn't start after the secret is replaced? Any help would be appreciated.

Thanks!

In my opinion Docker Swarm secret (and config) are sh#t, because you can't update. You have to tear down your active stack/services/containers using it, re-create the secret and restart your stack/services/containers.

If you think there is an issue with Traefik not starting, then I would enable and check Traefik debug logs.

Disclaimer: we use config and secret with Docker Swarm, e.g. for paid wildcards :wink:

I would suggest letting Traefik handle SSL.
Heres is the portainer.yml that will allow it to happen.

version: '3.2'

services:
  agent:
    image: portainer/agent:latest
    environment:
      # REQUIRED: Should be equal to the service name prefixed by "tasks." when
      # deployed inside an overlay network
      AGENT_CLUSTER_ADDR: tasks.agent
      # AGENT_PORT: 9001
      # LOG_LEVEL: debug
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer-ce:latest
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    volumes:
      - data:/data
    networks:
      - traefik-net
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.portainer.rule=Host(`portainer.xyz.com`)"
        - "traefik.http.routers.portainer.entrypoints=websecure"
        - "traefik.http.routers.portainer.tls=true"
        - "traefik.http.routers.redirect-https.entrypoints=web"
        - "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
        - "traefik.http.routers.redirect-https.rule=hostregexp(`{host:.+}`)"
        - "traefik.http.services.portainer.loadbalancer.passhostheader=true"
        - "traefik.http.services.portainer.loadbalancer.server.port=9000"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
networks:
  traefik-net:
    external: true
  agent_network:
    external: true

volumes:
   data:

Here is the traefik.yml that goes along with it


version: '3.3'
services:
reverse-proxy:
image: traefik:v2.8.4
command:
- --api=true
- --api.dashboard=true
- --log.level=DEBUG
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-net
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.file.directory=/config/
- --providers.file.watch=true
- --metrics.prometheus=true
- --entryPoints.metrics.address=:8888
- --metrics.prometheus.entryPoint=metrics

ports:
  - target: 443
    published: 443
    mode: host
  - target: 80
    published: 80
    mode: host
  - target: 8888
    published: 8888
    mode: host
volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro
  - /root/ops/config:/config
networks:
  - traefik-net

deploy:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik-xyz.com`)"
        # - "traefik.docker.network=app-entry"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.redirect-traefik.entrypoints=web"
      - "traefik.http.routers.redirect-traefik.middlewares=redirect-traefik"
      - "traefik.http.routers.redirect-traefik.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.middlewares.redirect-traefik.redirectscheme.scheme=https" 
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$2y$$10$$eJ6QmHskSRSnNcoqVkRFHu/oiIU9f4HGhPQORgerKD2AP/yQ0IoWe"
      - "traefik.http.services.traefik.loadbalancer.server.port=1337"
    placement:
      constraints:
        - node.role == manager

networks:
traefik-net:
external: true

Pre-requisites

  1. Network:
    Create the relevant network
docker network create -d overlay traefik-net --attachable
docker network create -d overlay agent_network
  1. TOML file and Certificates:
    Ensure that the mounted volume in traefik yml: - /root/ops/config:/config has an ssl.toml file, like the one below, along with your certs.

[tls.stores.default.defaultCertificate]
certFile = "/config/server.pem"
keyFile = "/config/server.pem"

Hope this helps

Thanks for the replies! I think I like the idea of traefik handling the ssl. I will test it out

Just be aware that if you mount a folder into the Traefik container with the dynamic config file and cert files, that you need to manually update them on every Traefik node - probably every year.

If you have many nodes and many custom certs that need renew throughout the year, you could use a shared folder you mount on the nodes or you can even mount a shared folder directly as Docker volume.