SSL cert invalid [Traefik v2.2.8]

Hello People, I have set up a new fastAPI project generated form the the latest release 0.5.0 . which has traefik v2.2 baked in. Everything is working well locally. However on staging i am have a an SSL cert issue with traefik. Both PGadmin and Flower are getting issued with valid SSL certs, however the backend and frontend domains have invalid certs which look to be issued by TRAEFIK DEFAULT CERT .

They are all under the same subdomain, I used the https://dockerswarm.rocks/traefik/ guide and generated my project from here: https://github.com/tiangolo/full-stack-fastapi-postgresql

is there a way to force the backend and the front end to use get valid certs, here is the docker compose file

version: "3.3"
services:

  proxy:
    image: traefik:v2.2
    networks:
      - ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
      - default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command:
      # Enable Docker in Traefik, so that it reads labels from Docker services
      - --providers.docker
      # Add a constraint to only use services with the label for this stack
      # from the env var TRAEFIK_TAG
      - --providers.docker.constraints=Label(`traefik.constraint-label-stack`, `${TRAEFIK_TAG?Variable not set}`)
      # Do not expose all Docker services, only the ones explicitly exposed
      - --providers.docker.exposedbydefault=false
      # Enable Docker Swarm mode
      - --providers.docker.swarmmode
      # Enable the access log, with HTTP requests
      - --accesslog
      # Enable the Traefik log, for configurations and errors
      - --log
      # Enable the Dashboard and API
      - --api
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        # Enable Traefik for this service, to make it available in the public network
        - traefik.enable=true
        # Use the traefik-public network (declared below)
        - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
        # Use the custom label "traefik.constraint-label=traefik-public"
        # This public Traefik will only use services with this label
        - traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
        # traefik-http set up only to use the middleware to redirect to https
        - traefik.http.middlewares.${STACK_NAME?Variable not set}-https-redirect.redirectscheme.scheme=https
        - traefik.http.middlewares.${STACK_NAME?Variable not set}-https-redirect.redirectscheme.permanent=true
        # Handle host with and without "www" to redirect to only one of them
        # Uses environment variable DOMAIN
        # To disable www redirection remove the Host() you want to discard, here and
        # below for HTTPS
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-http.rule=Host(`${DOMAIN?Variable not set}`) || Host(`www.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-http.entrypoints=http
        # traefik-https the actual router using HTTPS
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.rule=Host(`${DOMAIN?Variable not set}`) || Host(`www.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.entrypoints=https
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.tls=true
        # Use the "le" (Let's Encrypt) resolver created below
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.tls.certresolver=le
        # Define the port inside of the Docker service to use
        - traefik.http.services.${STACK_NAME?Variable not set}-proxy.loadbalancer.server.port=80
        # Handle domain with and without "www" to redirect to only one
        # To disable www redirection remove the next line
        - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.regex=^https?://(www.)?(${DOMAIN?Variable not set})/(.*)
        # Redirect a domain with www to non-www
        # To disable it remove the next line
        - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.replacement=https://${DOMAIN?Variable not set}/$${3}
        # Redirect a domain without www to www
        # To enable it remove the previous line and uncomment the next
        # - traefik.http.middlewares.${STACK_NAME}-www-redirect.redirectregex.replacement=https://www.${DOMAIN}/$${3}
        # Middleware to redirect www, to disable it remove the next line 
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.middlewares=${STACK_NAME?Variable not set}-www-redirect
        # Middleware to redirect www, and redirect HTTP to HTTPS
        # to disable www redirection remove the section: ${STACK_NAME?Variable not set}-www-redirect,
        - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-http.middlewares=${STACK_NAME?Variable not set}-www-redirect,${STACK_NAME?Variable not set}-https-redirect

  db:
    image: postgres:12
    volumes:
      - app-db-data:/var/lib/postgresql/data/pgdata
    env_file:
      - .env
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
    deploy:
      placement:
        constraints:
          - node.labels.${STACK_NAME?Variable not set}.app-db-data == true

  pgadmin:
    image: dpage/pgadmin4
    networks:
      - ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
      - default
    depends_on:
      - db
    env_file:
      - .env
    deploy:
      labels:
        - traefik.enable=true
        - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
        - traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-http.rule=Host(`pgadmin.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-http.entrypoints=http
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-http.middlewares=${STACK_NAME?Variable not set}-https-redirect
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-https.rule=Host(`pgadmin.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-https.entrypoints=https
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-https.tls=true
        - traefik.http.routers.${STACK_NAME?Variable not set}-pgadmin-https.tls.certresolver=le
        - traefik.http.services.${STACK_NAME?Variable not set}-pgadmin.loadbalancer.server.port=5050

  queue:
    image: rabbitmq:3
    # Using the below image instead is required to enable the "Broker" tab in the flower UI:
    # image: rabbitmq:3-management
    #
    # You also have to change the flower command
  
  flower:
    image: mher/flower
    networks:
      - ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
      - default
    env_file:
      - .env
    command:
      - "--broker=amqp://guest@queue:5672//"
      # For the "Broker" tab to work in the flower UI, uncomment the following command argument,
      # and change the queue service's image as well
      # - "--broker_api=http://guest:guest@queue:15672/api//"
    deploy:
      labels:
        - traefik.enable=true
        - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
        - traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-http.rule=Host(`flower.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-http.entrypoints=http
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-http.middlewares=${STACK_NAME?Variable not set}-https-redirect
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-https.rule=Host(`flower.${DOMAIN?Variable not set}`)
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-https.entrypoints=https
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-https.tls=true
        - traefik.http.routers.${STACK_NAME?Variable not set}-flower-https.tls.certresolver=le
        - traefik.http.services.${STACK_NAME?Variable not set}-flower.loadbalancer.server.port=5555
  
  backend:
    image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
    depends_on:
      - db
    env_file:
      - .env
    environment:
      - SERVER_NAME=${DOMAIN?Variable not set}
      - SERVER_HOST=https://${DOMAIN?Variable not set}
      # Allow explicit env var override for tests
      - SMTP_HOST=${SMTP_HOST}
    build:
      context: ./backend
      dockerfile: backend.dockerfile
      args:
        INSTALL_DEV: ${INSTALL_DEV-false}
    deploy:
      labels:
        - traefik.enable=true
        - traefik.constraint-label-stack=${TRAEFIK_TAG?Variable not set}
        - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=PathPrefix(`/api`) || PathPrefix(`/docs`) || PathPrefix(`/redoc`)
        - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=80
  
  celeryworker:
    image: '${DOCKER_IMAGE_CELERYWORKER?Variable not set}:${TAG-latest}'
    depends_on:
      - db
      - queue
    env_file:
      - .env
    environment:
      - SERVER_NAME=${DOMAIN?Variable not set}
      - SERVER_HOST=https://${DOMAIN?Variable not set}
      # Allow explicit env var override for tests
      - SMTP_HOST=${SMTP_HOST?Variable not set}
    build:
      context: ./backend
      dockerfile: celeryworker.dockerfile
      args:
        INSTALL_DEV: ${INSTALL_DEV-false}
  
  frontend:
    image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'
    build:
      context: ./frontend
      args:
        FRONTEND_ENV: ${FRONTEND_ENV-production}
    deploy:
      labels:
        - traefik.enable=true
        - traefik.constraint-label-stack=${TRAEFIK_TAG?Variable not set}
        - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=PathPrefix(`/`)
        - traefik.http.services.${STACK_NAME?Variable not set}-frontend.loadbalancer.server.port=80

volumes:
  app-db-data:

networks:
  traefik-public:
    # Allow setting it to false for testing
    external: ${TRAEFIK_PUBLIC_NETWORK_IS_EXTERNAL-true}

From the configuration posted it does not appear that there is any TLS configured on frontend or backend. Certificate is a concept specific to TLS, if you do not have TLS you do not have a cert either.

Thanks @zespri, should a label addition like this fix it:

- traefik.http.routers.${STACK_NAME?Variable not set}-flower-https.tls=true

Or do i need to specify the https-entry-point and certificate resolver ? I am not exactly hence i am asking

I have no idea what fastAPI is and how it is supposed to wire traefik up, so there could be some unfulfilled expectations on that end.

That aside the doco about TLS and LE is here:

https://docs.traefik.io/https/overview/
https://docs.traefik.io/https/tls/
https://docs.traefik.io/https/acme/

Whether or not you need a cert resolver depends on your requirements. If you want traefik to request certificates from LE and use these certificates you will need to attach/configure a cert resolver to your router. If you want to specify your own certificates this is not required, but you will have to configure traefik to use them.

thanks for the pointers after adding the docker.network label and tls on both services it works now

        - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
        - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls=true
        - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls.certresolver=le       

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.