使用traefik时如何映射docker容器内的特定端口?

Des*_*ond 7 reverse-proxy docker traefik

这是我的docker-compose.yml

version: '3'
services:
  website:
    build: ./website
    expose: [3000]
    labels:
      - "traefik.frontend.rule=Host:localhost"
  blog:
    build: ./blog
    expose: [4000]
    labels:
      - "traefik.frontend.rule=Host:localhost;PathPrefix:/blog"
  docs:
    build: ./docs
    expose: [3000]
    labels:
      - "traefik.frontend.rule=Host:localhost;PathPrefix:/docs"
  proxy:
    image: traefik
    command: --api.insecure=true --providers.docker
    networks:
      - webgateway
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

networks:
  webgateway:
    driver: bridge
Run Code Online (Sandbox Code Playgroud)

我想要的是通过不同的路由访问三个不同的 node.js 网站。但这三个 node.js 网站实际上公开了不同的端口。现在我的 treafik 正在运行。我可以通过localhost:8080But进行配置,localhost localhost/blog并且localhost/docs都是404 page not found

PS:我不确定端口是否是我应该调查的问题,因为将一个 node.js 服务更改为port 80并不能解决难题。我在 traefik 仪表板上看到规则是Host( blog-dev)

Fac*_*cty 7

labels: 
- traefik.http.services.<YOUR-SERVICE-NAME>.loadbalancer.server.port=9763
Run Code Online (Sandbox Code Playgroud)

例如:

services:
  wso:
    image: "my-custom-wso-image"
    volumes:
      - .....
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wso.tls=true"
      - "traefik.http.routers.wso.rule=Host(`my.nice.url`)"
      - "traefik.http.services.wso.loadbalancer.server.port=9763" #<-----
Run Code Online (Sandbox Code Playgroud)


Kei*_*ith 6

PathPrefix:/blog

当您将此作为路由规则时,traefix 不会在发送到容器时自动删除前缀。

因此,除非您/blog的容器内有路由,否则您将收到 404。

所以你通常做的也是添加一个中间件来剥离这个 -> https://docs.traefik.io/middlewares/stripprefix/

此外,您似乎没有根据您的服务设置规则。

因此,作为您的第一项服务的示例blog

尝试->

labels:
    - "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)"
    - "traefik.http.routers.blog.middlewares=strip-blog"
    - "traefik.http.middlewares.strip-blog.stripprefix.prefixes=/blog"
Run Code Online (Sandbox Code Playgroud)

然后对你的其他路线做同样的事情,不要忘记routers.blogrouters.docs等替换。


Des*_*ond 5

感谢@Keith,我找到了解决方案

version: '3'
services:
  website:
    build: ./website
    expose: [3000]
    networks: # It's essential to specify the same network in every service
      - webgateway
    labels:
      - "traefik.http.routers.website.rule=Host(`localhost`)" # Use the right format
      - "traefik.port=3000" # Let traefik find the right port
  blog:
    build: ./blog
    expose: [4000]
    networks:
      - webgateway
    labels:
      - "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)" # blog has a root as `/blog` so no need to strip otherwise too many redirects
      - "traefik.port=4000"
  docs:
    build: ./docs
    expose: [3000]
    networks:
      - webgateway
    labels:
      - "traefik.http.routers.docs.rule=Host(`localhost`) && PathPrefix(`/docs`)"
      - "traefik.http.routers.docs.middlewares=strip-docs" # Necessary as Keith mentioned
      - "traefik.http.middlewares.strip-docs.stripprefix.prefixes=/docs"
      - "traefik.port=3000"
  proxy:
    image: traefik
    command: --api.insecure=true --providers.docker
    networks:
      - webgateway
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

networks:
  webgateway:
    driver: bridge
Run Code Online (Sandbox Code Playgroud)