You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Traefik与C# API:Docker Swarm下无端口HTTPS访问配置问题

问题描述

在Docker Swarm集群中部署了Traefik、Portainer及一个C# API服务,目前仅能通过带端口的URL(如http://example.com:8081/valid-route)访问API,无法直接通过域名example.com实现HTTPS无端口访问。尽管已为API的docker-compose配置了Traefik相关标签,但问题仍未解决,现寻求解决方案以实现API的无端口HTTPS访问。

现有配置

Traefik节点的docker-compose.yaml

version: "3.7"
services:

## --------------------------- ORION --------------------------- ##

  traefik:
    image: traefik:v2.11.2
    command:
      - "--api.dashboard=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=ConexxoHubNet" ## Nome da rede interna
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.transport.respondingTimeouts.idleTimeout=3600"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencryptresolver.acme.storage=/etc/traefik/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencryptresolver.acme.email=brunopeixoto@suasvendas.com" ## Email para receber as notificações
      - "--log.level=DEBUG"
      - "--log.format=common"
      - "--log.filePath=/var/log/traefik/traefik.log"
      - "--accesslog=true"
      - "--accesslog.filepath=/var/log/traefik/access-log"
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        - "traefik.enable=true"
        - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
        - "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"
        - "traefik.http.routers.http-catchall.rule=Host(`{host:.+}`)"
        - "traefik.http.routers.http-catchall.entrypoints=web"
        - "traefik.http.routers.http-catchall.middlewares=redirect-https@docker"
        - "traefik.http.routers.http-catchall.priority=1"
    volumes:
      - "vol_certificates:/etc/traefik/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host
    networks:
      - MySwarmNet ## Nome da rede interna

## --------------------------- ORION --------------------------- ##

volumes:
  vol_shared:
    external: true
    name: volume_swarm_shared
  vol_certificates:
    external: true
    name: volume_swarm_certificates

networks:
  MySwarmNet: ## Nome da rede interna
    external: true
    attachable: true
    name: MySwarmNet ## Nome da rede interna

Portainer的docker-compose.yaml

version: "3.7"
services:

## --------------------------- ORION --------------------------- ##

  agent:
    image: portainer/agent:latest ## Versão do portainer

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes

    networks:
      - MySwarmNet ## Nome da rede interna

    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

## --------------------------- ORION --------------------------- ##

  portainer:
    image: portainer/portainer-ce:latest
    command: -H tcp://tasks.agent:9001 --tlsskipverify

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

    networks:
      - MySwarmNet ## Nome da rede interna

    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.portainer.rule=Host(`portainer.conexxohub.com.br`)" ## Dominio da aplicação
        - "traefik.http.services.portainer.loadbalancer.server.port=9000"
        - "traefik.http.routers.portainer.tls.certresolver=letsencryptresolver"
        - "traefik.http.routers.portainer.service=portainer"
        - "traefik.docker.network=ConexxoHubNet" ## Nome da rede interna
        - "traefik.http.routers.portainer.entrypoints=websecure"
        - "traefik.http.routers.portainer.priority=1"

## --------------------------- ORION --------------------------- ##

networks:
  MySwarmNet: ## Nome da rede interna
    external: true
    attachable: true

volumes:
  portainer_data:
    external: true
    name: portainer_data

C# API的docker-compose.yaml

version: '3.3'

services:
  api:
    image: dockerhub-image-name/image-name
    ports:
      - "8081:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production  
    deploy:
        mode: replicated
        replicas: 1
        placement:
          constraints:
            - node.role == manager
        labels:
          - traefik.enable=true
          - traefik.http.routers.api.rule=Host(`example.com`)
          - traefik.http.services.api.loadbalancer.server.port=8081
          - traefik.http.routers.api.service=cadvisor
          - traefik.http.routers.api.tls.certresolver=letsencryptresolver
          - traefik.http.routers.api.entrypoints=websecure
          - traefik.http.routers.api.tls=true
    networks:
      - MySwarmNet

networks:
  MySwarmNet:
    external: true
解决方案

核心问题分析

  1. 网络不一致:Traefik配置中--providers.docker.network=ConexxoHubNet,但Traefik自身加入的是MySwarmNet,且API服务也在MySwarmNet,导致Traefik无法发现API服务。
  2. 服务名称错误:API的Traefik标签中traefik.http.routers.api.service=cadvisor,服务名应为api(与docker-compose中定义的服务名一致)。
  3. 端口配置错误:traefik.http.services.api.loadbalancer.server.port应该指向容器内部的8080,而非宿主机映射的8081——Traefik与容器在同一Swarm网络中,直接访问容器端口即可。
  4. 冗余端口映射:API服务不需要配置ports映射到宿主机,Traefik会通过Swarm网络代理请求,暴露端口反而可能引发冲突。

修正后的配置

1. 修正Traefik的网络配置

将Traefik的--providers.docker.network改为MySwarmNet,与自身加入的网络一致:

# Traefik command中的对应行修改为
- "--providers.docker.network=MySwarmNet"

2. 修正C# API的docker-compose.yaml

version: '3.3'

services:
  api:
    image: dockerhub-image-name/image-name
    environment:
      - ASPNETCORE_ENVIRONMENT=Production  
    deploy:
        mode: replicated
        replicas: 1
        placement:
          constraints:
            - node.role == manager
        labels:
          - traefik.enable=true
          - traefik.http.routers.api.rule=Host(`example.com`)
          - traefik.http.services.api.loadbalancer.server.port=8080
          - traefik.http.routers.api.service=api
          - traefik.http.routers.api.tls.certresolver=letsencryptresolver
          - traefik.http.routers.api.entrypoints=websecure
          - traefik.http.routers.api.tls=true
          - traefik.docker.network=MySwarmNet # 明确指定与Traefik一致的网络
    networks:
      - MySwarmNet

networks:
  MySwarmNet:
    external: true

验证步骤

  1. 重新部署Traefik:docker stack deploy -c traefik-compose.yaml traefik
  2. 重新部署API服务:docker stack deploy -c api-compose.yaml api
  3. 查看Traefik日志确认是否发现API路由:docker logs <traefik-container-id>
  4. 访问https://example.com/valid-route验证是否正常访问

内容的提问来源于stack exchange,提问作者Bruno Henrique Peixoto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:40:56