Reputation: 1476
I have a docker swarm configured to use Traefik as reverse proxy. One of the containers in my swarm is running an Nginx server but I am getting a 502 Bad Gateway
error when I navigate to that particular endpoint. Traefik is setup as follows:
version: '3.5'
services:
traefik:
image: traefik:alpine
command: |-
--entryPoints="Name:http Address::80 Redirect.EntryPoint:https"
--entryPoints="Name:https Address::443 TLS"
--defaultentrypoints="http,https"
--accesslogsfile="/var/log/access.log"
--acme
--acme.acmelogging="true"
--acme.domains="${SERVER},${SANS1}"
--acme.email="${ACME_EMAIL}"
--acme.entrypoint="https"
--acme.httpchallenge
--acme.httpchallenge.entrypoint="http"
--acme.storage="/opt/traefik/acme.json"
--acme.onhostrule="true"
--docker
--docker.swarmmode
--docker.domain="${SERVER}"
--docker.network="frontend"
--docker.watch
--api
networks:
- frontend
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
- target: 8080
published: 8080
mode: host
volumes:
- traefik_acme:/opt/traefik
- traefik_logs:/var/log/access.log
- /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
networks:
frontend:
name: "frontend"
driver: overlay
volumes:
traefik_acme:
traefik_logs:
This compose file provides the overlay
network and the Traefik service. The rest of my swarm is defined in the following compose file:
version: "3.5"
services:
test:
image: emilevauge/whoami
deploy:
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER};PathPrefixStrip:/test"
traefik.port: 80
networks:
- frontend
octeditor:
image: ${DOCKER_OCTEDITOR_IMAGE_TAG}
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER}"
traefik.port: 3000
networks:
- frontend
ports:
- "3000:80"
octserver:
image: ${DOCKER_OCTSERVER_IMAGE_TAG}
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER};PathPrefixStrip:/api"
traefik.port: 4000
networks:
- frontend
ports:
- "4000:4000"
visualizer:
image: dockersamples/visualizer:stable
deploy:
placement:
constraints:
- 'node.role == manager'
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER};PathPrefixStrip:/visualizer"
traefik.port: 8001
networks:
- frontend
ports:
- "8001:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
frontend:
external: true
The relevant configuration is for the octeditor
service:
octeditor:
image: ${DOCKER_OCTEDITOR_IMAGE_TAG}
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER}"
traefik.port: 3000
networks:
- frontend
ports:
- "3000:80"
I'm mapping port 80 (which Nginx listens to by default) to port 3000 where Traefik
is configured to locate this service. This is the Dockerfile
for the service running Nginx:
FROM node:latest as builder
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
I simply build a react app
and copy the build folder to the /usr/share/nginx/html
folder. I've tried building and running this Dockerfile as a standalone container and it works, also I've checked the contents of the html
folder and everything looks correct. The other services, apart from the visualizer
service, are running correctly. Only this octedtior
service and the visualizer
service are giving me 502
errors. Can anyone suggest a solution or even how to check the traffic being sent to the nginx container? I've tried docker ps servicename
but I can't see any errors coming from the service.
Edit:
If I change the configuration of the octeditor
to this:
octeditor:
image: ${DOCKER_OCTEDITOR_IMAGE_TAG}
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER}"
traefik.port: 80
networks:
- frontend
ports:
- "80:80"
And remove the test
service that was previously listening on port 80
it seems to work. I don't understand what was wrong with the previous configuration however? I thought I was mapping traffic from port 3000 to port 80 of the container before, whereas now I'm mapping from port 80 to 80, but nothing should have changed from the perspective of the container, right?
Upvotes: 0
Views: 545
Reputation: 263637
The relevant configuration is for the octeditor service:
octeditor: image: ${DOCKER_OCTEDITOR_IMAGE_TAG} deploy: replicas: 1 labels: traefik.enable: "true" traefik.frontend.rule: "Host:${SERVER}" traefik.port: 3000 networks: - frontend ports: - "3000:80"
I'm mapping port 80 (which Nginx listens to by default) to port 3000 where Traefik is configured to locate this service.
The traefik port needs to be 80, not 3000. The port mapping will create a forward from the host on 3000 to the container on 80. However traefik talks directly to the container over a shared network (frontend
) and you need to provide it the container port.
There is no need to publish a host port for services accessed through traefik or any other reverse proxy unless you need to access them directly without the proxy (which brings into question whether you need a reverse proxy in those scenarios). In other words, this could be written without the ports:
octeditor:
image: ${DOCKER_OCTEDITOR_IMAGE_TAG}
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.frontend.rule: "Host:${SERVER}"
traefik.port: 80
networks:
- frontend
Upvotes: 1