Redirect http to https

Hi,

I've been struggling with creating the redirect from http to https. At this moment in access log I get
"GET / HTTP/1.1" 404 19 "-" "-" 99 "-" "-" 0ms when I visit http, when I visit https i get
"GET / HTTP/2.0" 200 93343 "-" "-" 137 "app-fe@docker" "http://172.25.0.3:3000" 134ms

I've tried following numerous guides for creating the middleware and router for this, I've tried to establish secure dashboard access, but no luck.

This is my current compose file. I would really need some pointers on what I'm doing wrong.

# docker-compose.yml
version: "3"
services:
  reverse-proxy:
    image: traefik:v2.10
    restart: always
    command: 
      - --api.insecure=true 
      - --api.dashboard=true
      - --providers.docker 
      - --api.debug=true 
      - --log.level=DEBUG
      - "--providers.docker.exposedbydefault=false"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=myemail@email.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - --accessLog=true
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    volumes:
      - "./letsencrypt:/letsencrypt"
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - "traefik.frontend.rule=Host:www.mywebsite.com"
      - "traefik.port=8080"
      - "traefik.http.routers.myrouter.rule=Host(`www.mywebsite.com`)"

      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.myrouter.entrypoints=web"
      - "traefik.http.routers.myrouter.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.myrouter.middlewares=redirect-to-https"

      - "traefik.http.routers.dashboard.entrypoints=web"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.mywebsite.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.dashboard.service=api@internal"

  app-fe:
    image: app-fe:latest
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app-fe.rule=Host(`www.mywebsite.com`)"
      - "traefik.http.routers.app-fe.rule=PathPrefix(`/`)"
      - "traefik.http.routers.app-fe.service=app-fe"
      - "traefik.http.services.app-fe.loadbalancer.server.port=3000"
      - "traefik.http.routers.app-fe.entrypoints=websecure"
      - "traefik.http.routers.app-fe.tls.certresolver=myresolver"

  app-be:
    image: app-be:latest
    restart: always

    depends_on:
      db:
        condition: service_healthy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app-be.rule=Host(`www.mywebsite.com`) && PathPrefix(`/api/v1`)"
      - "traefik.http.routers.app-be.service=app-be"
      - "traefik.http.services.app-be.loadbalancer.server.port=3001"
      - "traefik.http.routers.app-be.entrypoints=websecure"
      - "traefik.http.routers.app-be.tls.certresolver=myresolver"

  db:
    image: postgres:15.4
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 10s
      retries: 3
    environment:
      PGDATA: /var/lib/postgresql/data
    volumes:
      - ./db-data:/var/lib/postgresql/data
  pgadmin:
    container_name: pgadmin4_container
    image: dpage/pgadmin4
    restart: always
    links:
      - db:pgsql-server
    volumes: 
     - pgadmin-data:/var/lib/pgadmin
    ports:
      - 5050:8001
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pgadmin.rule=Host(`www.mywebsite.com`) && PathPrefix(`/pgadmin-web`)"
      - "traefik.http.routers.pgadmin.service=pgadmin"
      - "traefik.http.services.pgadmin.loadbalancer.server.port=8001"
      - "traefik.http.routers.pgadmin.entrypoints=websecure"
      - "traefik.http.routers.pgadmin.tls.certresolver=myresolver"
volumes:
  db-data: null
  pgadmin-data: null


You can only have one .rule= per Traefik router (with the same name).

Usually apps don’t like to be places under a PathPrefix, they expect to be in root (/). They will redirect, link and load images and scripts with absolute paths. To make it work, they would need some kind of base-path setting to adjust. That’s why usage of sub-domains is best practice.

Some images (declare to) expose multiple ports in Dockerfile, choose which one to use.

Don’t expose the ports of services/containers other that Traefik, as that might circumvent security middlewares and might disable TLS. This is not necessary when using a Docker network, Traefik will reach the ports internally.

Check and compare to simple Traefik example. To make it clean when using Traefik v2, add .entrypoints=websecure to each router.

1 Like