【问题标题】:Docker Swarm Nginx Service behind Traefik giving a 502 ErrorTraefik 背后的 Docker Swarm Nginx 服务给出 502 错误
【发布时间】:2019-06-25 07:48:14
【问题描述】:

我有一个 docker swarm 配置为使用 Traefik 作为反向代理。我的 swarm 中的一个容器正在运行 Nginx 服务器,但是当我导航到该特定端点时出现502 Bad Gateway 错误。 Traefik 设置如下:

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:

此 compose 文件提供 overlay 网络和 Traefik 服务。我的 swarm 的其余部分在以下 compose 文件中定义:

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

相关配置针对octeditor服务:

  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"

我将端口 80(Nginx 默认侦听)映射到端口 3000,其中 Traefik 配置为定位此服务。这是运行 Nginx 的服务的Dockerfile

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

我只是构建一个react app 并将构建文件夹复制到/usr/share/nginx/html 文件夹。我尝试将这个 Dockerfile 作为独立容器构建和运行,它可以工作,我还检查了 html 文件夹的内容,一切看起来都正确。除visualizer 服务外,其他服务均正常运行。只有这个octedtior 服务和visualizer 服务给我502 错误。任何人都可以提出解决方案,甚至如何检查发送到 nginx 容器的流量吗?我试过docker ps servicename,但我看不到来自服务的任何错误。

编辑:

如果我将octeditor 的配置更改为:

  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"

并删除之前在端口80 上侦听的test 服务,它似乎可以工作。我不明白以前的配置有什么问题?之前我以为我是从容器的 3000 端口映射到 80 端口的流量,而现在我是从 80 端口映射到 80 端口,但是从容器的角度来看应该没有什么改变吧?

【问题讨论】:

    标签: docker nginx traefik


    【解决方案1】:

    相关配置是针对octeditor服务的:

    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"
    

    我将端口 80(Nginx 默认监听)映射到端口 3000 Traefik 配置为定位此服务的位置。

    traefik 端口需要为 80,而不是 3000。端口映射将创建从 3000 上的主机到 80 上的容器的转发。但是,traefik 通过共享网络 (frontend) 直接与容器通信,而您需要提供容器端口。

    没有必要为通过 traefik 或任何其他反向代理访问的服务发布主机端口,除非您需要在没有代理的情况下直接访问它们(这会让人怀疑在这些情况下您是否需要反向代理)。换句话说,这可以在没有端口的情况下编写:

      octeditor:
        image: ${DOCKER_OCTEDITOR_IMAGE_TAG}
        deploy:
          replicas: 1
          labels:
            traefik.enable: "true"
            traefik.frontend.rule: "Host:${SERVER}"
            traefik.port: 80
        networks:
          - frontend
    

    【讨论】:

    • 谢谢!这解决了问题。我不明白 -ports 选项实际上在做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多