如何使用Docker管理暴露在端口80上的多个端口?

时间:2019-09-21 18:03:25

标签: docker-compose port traefik

我有以下设置:

version: '3'

services:
  traefik:
    image: traefik:v2.0
    container_name: traefik
    ports:
      - 80:80
    command:
      - --api.debug=true
      - --api.insecure=true
      - --providers.docker=true
      - --entrypoints.web.address=:80
      - --providers.docker.exposedByDefault=true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - traefik.http.routers.traefik.service=api@internal
      - traefik.http.routers.traefik.rule=Host(`monitor.domain.org`)
      - traefik.http.routers.traefik.entrypoints=web
    networks:
      - web
  db:
    image: registry.domain.com/repo/db:latest
    container_name: db
    restart: always
    networks:
      - internal
  api:
    image: registry.domain.com/repo/api:latest
    container_name: api
    ports:
      - 80:3001
    volumes:
      - /root/rsa.pem:/root/certs/rsa.pem
      - /root/rsa_pub.pem:/root/certs/rsa_pub.pem
    restart: always
    depends_on:
      - db
    environment:
      - MAIL_ADDRESS=${MAIL_ADDRESS}
      - MAIL_PASSWORD=${MAIL_PASSWORD}
      - MAIL_HOST=${MAIL_HOST}
    labels:
      - traefik.http.routers.api.rule=Host(`api.domain.org`)
      - traefik.http.routers.api.entrypoints=web
    networks:
      - internal
      - web
  app:
    image: registry.domain.com/repo/app:latest
    container_name: app
    restart: always
    depends_on:
      - api
      - db
    labels:
      - traefik.http.routers.app.rule=Host(`domain.org`,`www.domain.org`)
      - traefik.http.routers.app.entrypoints=web
    networks:
      - web

networks:
  web:
    external: true
  internal:
    external: false

很显然,我从docker收到一个错误,说Bind for 0.0.0.0:80 failed: port is already allocated。单独公开port 80服务的traefikapi服务都是完美的。如果我没有在这两个服务上公开port 80,则对两个服务均无效。在Nginx上运行的app服务可以正常运行,而不会无缝暴露port 80。如何使apitraefik服务在port 80上一起运行?

1 个答案:

答案 0 :(得分:2)

实际上,您需要对api做与对应用程序相同的操作,并通过traefik公开它。

通常,您通常希望通过traefik(或任何其他反向代理)公开所有群集内部服务,因此,只有traefik是应公开给主机端口的人。您的所有其他服务将仅注册到至少entrypoint个traefik中以获取请求。

因此,您只需要从您的api服务中删除ports: - 80:3001

将会发生的情况是,traefik仅侦听端口80,并且所有具有domain.orgwww.domain.org的http主机头的traefik将被路由到应用程序服务,尽管所有带有{{1 }}将被路由到您的api服务。

如果您已完成上述操作,但无法将请求发送到api服务,请共享服务中的一些日志以检查错误,在大多数情况下,某些标头需要传播到后端服务才能正常工作。

PS。您正在使用traefik的最新v2.0版本,其中将服务注册到入口点显然足以使traefik将请求路由到该服务。在以前的版本中,您应该在服务中添加标签api.domain.org,以便公布服务正在侦听的位置,这对于正在发生的事情更为明确。 docs