我用 Traefik、Portainer 和一些 API 托管一个 swarm,在本例中是 C# API。即使 API docker-compose 上的 traefik 标签应该是正确的,我也无法在没有端口的情况下访问我的 URL。预先感谢您的帮助!
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:
- ConexxoHubNet ## 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:
- ConexxoHubNet ## 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:
ConexxoHubNet: ## Nome da rede interna
external: true
attachable: true
name: ConexxoHubNet ## Nome da rede interna
volumes:
portainer_data:
external: true
name: portainer_data
最后,将 API 镜像推送到 Docker Hub 后,我在 Portainer 上推送以下文件
docker-compose.yaml
。这里的域不是功能性的,这需要一些思考。可以看到,8081端口是可访问的端口。但是,当我尝试访问 example.com
时,访问端点的唯一方法是通过 URL http://example.com:8081/valid-route
。我想让它也适用于 https
并且没有端口要求。这样做需要什么?
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
loadbalancer.server.port=8080
应设置为 Docker 容器内部端口,因为 Traefik 通常通过 Docker 网络进行连接。所以 ports:
在这种情况下是不相关的。
我根本不会将
ports:
用于目标服务,因为它使它们可以在外部端口上使用,从而可能绕过任何 Traefik 安全中间件。