I host a swarm with Traefik, Portainer and some APIs, in this case, a C# API. I am unable to access my URL without the port, even though the traefik tags on API docker-compose are supposedly correct. Thanks in advance for your help!
The Traefik node has following file 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
Likewise, the portainer file docker-compose.yaml
is below:
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
Finally, after I push the API image to Docker Hub, I push the following file docker-compose.yaml
on Portainer. The domain here is not functional, which requires a bit of mind stretching. As you can see, the port 8081 is the accessible port. However, when I try to access example.com
, the only way to access the endpoints is by URL http://example.com:8081/valid-route
. I want to make it also available for https
and without the port requirement. What is necessary to do so?
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
should be set to the Docker container internal port, as Traefik usually connects via the Docker network. So ports:
is not relevant in that context.
I would not use ports:
at all for target services, as it makes them available on external ports, potentially circumventing any Traefik security middleware.