首页 > 解决方案 > Traefik 与 Let's Encrypt

问题描述

我正在尝试将 Let's Encrypt 与 Traefic 一起使用,但无论我如何设置msg="http: TLS handshake error from 193.174.362.742:65260: remote error: tls: bad certificate",浏览器总是会收到错误消息,说证书仅对 traefik 默认有效。此外,我无法将 http 流量重定向到 https。当我使用 http 时,网站会正常加载,而不是重定向和使用 https。

如果我连接到 traefik 容器,我可以看到 acme.json 文件在那里,但它总是空的。

我已经没有尝试新事物的想法了。有人有什么建议吗?

version: "3.7"
services:
  proxy:
    image: traefik
    networks:
      - ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
      - default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - volume_traefik:/letsencrypt
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    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

      - --entrypoints.web.address=:80
      - --entrypoints.web-secured.address=:443

      - --certificatesResolvers.le.acme.email=${LETS_ENCRYPT_EMAIL?Variable not set}
      - --certificatesResolvers.le.acme.storage=letsencrypt/acme.json
      - --certificatesResolvers.le.acme.httpChallenge=true
      - --certificatesResolvers.le.acme.httpChallenge.entryPoint=${TRAEFIK_PUBLIC_NETWORK?Veriable not set}

      # Enable the access log, with HTTP requests
      - --accesslog
      # Enable the Traefik log, for configurations and errors
      - --log.level=DEBUG
      - --log
      # Enable the Dashboard and API
      - --api.dashboard=true
      - --api
    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={$TRAEFIK_PUBLIC_NETWORK?Variable not set}
      #- 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:latest
    container_name: "test-postgres"
    volumes:
      - app-db-data:/var/lib/postgresql/data/pgdata
    env_file:
      - .env
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
    ports:
      - "5432:5432"

  backend:
    image: backend:latest
    depends_on:
      - db
    env_file:
      - .env
    build:
      context: ./backend
      dockerfile: Dockerfile
    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=443
      - traefik.http.routers.${STACK_NAME?Variable not set}-backend.tls=true

  frontend:
    image: frontend:latest
    build:
      context: ./frontend
      dockerfile: Dockerfile
    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=443
      - traefik.http.routers.${STACK_NAME?Variable not set}-frontend.tls=true


volumes:
  app-db-data:
  volume_traefik:

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

编辑:我现在让我们加密工作,但仍然无法获得 www 地址以转发到非 www 地址。

version: "3.7"
    services:
      proxy:
        image: traefik
        networks:
          - ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
          - default
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - volume_traefik:/letsencrypt
        ports:
          - "80:80"
          - "443:443"
          - "8080:8080"
        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

          - --entrypoints.web.address=:80
          - --entrypoints.web-secured.address=:443
          - --entrypoints.web.http.redirections.entryPoint.to=websecure
          - --entrypoints.web.http.redirections.entryPoint.scheme=https
          - --entrypoints.websecure.address=:443
          - --entrypoints.websecure.http.tls.certResolver=le
          - --entrypoints.websecure.http.tls.domains[0].main=${DOMAIN?Variable not set}

          - --certificatesResolvers.le.acme.email=${LETS_ENCRYPT_EMAIL?Variable not set}
          - --certificatesResolvers.le.acme.storage=letsencrypt/acme.json
          - --certificatesResolvers.le.acme.httpChallenge=true
          - --certificatesResolvers.le.acme.httpChallenge.entryPoint=${TRAEFIK_PUBLIC_NETWORK?Veriable not set}

          # Enable the access log, with HTTP requests
          - --accesslog
          # Enable the Traefik log, for configurations and errors
          - --log.level=DEBUG
          - --log
          # Enable the Dashboard and API
          - --api.dashboard=true
          - --api
        labels:
          - traefik.enable=true
          - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
          - traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
          - 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
          - 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.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
          - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.tls.certresolver=le
          - traefik.http.services.${STACK_NAME?Variable not set}-proxy.loadbalancer.server.port=80
          - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.regex=^https?://(www.)?(${DOMAIN?Variable not set})/(.*)
          - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.replacement=https://${DOMAIN?Variable not set}/$${3}

          - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-https.middlewares=${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:latest
        container_name: "test-postgres"
        volumes:
          - app-db-data:/var/lib/postgresql/data/pgdata
        env_file:
          - .env
        environment:
          - PGDATA=/var/lib/postgresql/data/pgdata
        ports:
          - "5432:5432"

      backend:
        image: backend:latest
        depends_on:
          - db
        env_file:
          - .env
        build:
          context: ./backend
          dockerfile: Dockerfile
        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=443
          - traefik.http.routers.${STACK_NAME?Variable not set}-backend.tls=true

      frontend:
        image: frontend:latest
        build:
          context: ./frontend
          dockerfile: Dockerfile
        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=443
          - traefik.http.routers.${STACK_NAME?Variable not set}-frontend.tls=true


    volumes:
      app-db-data:
      volume_traefik:

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

标签: dockerdocker-composelets-encrypttraefik

解决方案


推荐阅读