【问题标题】:Use Traefik with Docker Compose to serve 2 services on the same host but different routes使用 Traefik 和 Docker Compose 在同一主机上提供 2 个服务,但路由不同
【发布时间】:2020-11-26 14:27:39
【问题描述】:

我有 2 个前端应用程序,都由 Nginx 在端口 80 提供服务

  1. app-login
  2. app-contacts

我正在尝试使用 Docker Compose 配置 Traefik 以实现此目的:

  • 两个应用都在同一主机上提供服务(例如 abc.com 或 localhost:4000)
  • app-login 将从 localhost:4000/login(或 abc.com/login)访问
  • app-contacts 将从 localhost:4000/contacts(或 abc.com/contacts)访问

但问题是:它不适用于我目前所做的。

以下是 2 个应用程序中的 2 个 Dockerfiledocker-compose.yml

app-loginDockerfile:

# build stage
FROM node:lts-alpine as build-stage

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

# production stage
FROM nginx:stable-alpine as production-stage

COPY --from=build-stage /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

app-contacts Dockerfile:(有点复杂,但和登录应用差不多)

### STAGE 1: Build the AngularJS app ###

FROM node:lts-alpine as build-stage

RUN apk --no-cache add git

WORKDIR /app

COPY package.json /app/

RUN npm install

COPY . .

# Production mode build
RUN npm run build:prod


### STAGE 2: Add Nginx for hosting the AngularJS app ###

FROM nginx:stable-alpine as production-stage

# Removes the default nginx html files
RUN rm -rf /usr/share/nginx/html/*

# Copy the bundle
COPY --from=build-stage /app/dist /usr/share/nginx/html

# Copy the default nginx.conf
COPY --from=build-stage /app/nginx.conf /etc/nginx/conf.d/default.conf

VOLUME ["/usr/share/nginx/html/env"]

EXPOSE 80

# Copy .env file and shell script to container
WORKDIR /usr/share/nginx/html
COPY ./scripts/generate_env.sh .
COPY .env .

# Add bash
RUN apk add --no-cache bash

# Make our shell script executable
RUN chmod +x generate_env.sh

# Start Nginx server
CMD ["/bin/bash", "-c", "/usr/share/nginx/html/generate_env.sh && nginx -g \"daemon off;\""]

docker-compose.yml

version: '3'

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.2
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

  app-login:
    image: app-login
    labels:
      - "traefik.http.routers.app-login.rule=Path(/login)"

  app-contacts:
    image: app-contacts
    labels:
      - "traefik.http.routers.app-contacts.rule==Path(/contacts)"

不知道我哪里做错了。

我搜索了 Google,发现有人在使用 https://www.getambassador.io/ 和这个堆栈,但我也不知道如何配置它。

谢谢。

【问题讨论】:

    标签: docker nginx docker-compose dockerfile traefik


    【解决方案1】:

    默认情况下,Traefik 侦听端口 80。您必须将“81:81”替换为“81:80”。在您的网络浏览器中,您必须使用端口 81,它将在 Traefik 容器中映射到 80。

    编辑:

    您的标签中有几个语法错误。

    • == 而不是最后一行的 =
    • 路径应该用 ``
    • 引用

    如果您检查 Traefik 仪表板 (http://localhost:8080/),您可以看到路由器状态和配置错误。

    使用您当前的配置,NGINX 应该在路径 /login 和 /contacts 上接受请求,而不是默认的 /。您可以使用下面的标签,如果您想在转发到 NGINX 之前删除路径部分(登录名或联系人),那么附加的 2 行很有用,以便 NGINX 监听默认 /。

      app-login:
        image: app-login
        labels:
          - "traefik.http.routers.app-login.rule=PathPrefix(`/login`)"
          - "traefik.http.routers.app-login.middlewares=app-login-stripprefix"
          - "traefik.http.middlewares.app-login-stripprefix.stripprefix.prefixes=/login"
    
      app-contacts:
        image: app-contacts
        labels:
          - "traefik.http.routers.app-contacts.rule=PathPrefix(`/contacts`)"
          - "traefik.http.routers.app-contacts.middlewares=app-contacts-stripprefix"
          - "traefik.http.middlewares.app-contacts-stripprefix.stripprefix.prefixes=/contacts"
    

    【讨论】:

    • 我将81:81 更新为80:80,但仍然无法正常工作。我可以docker-compose up -d,但在那之后,当我尝试去 localhost/login 或 localhost/contacts 时,它说404 page not found。顺便说一句,如果我有这个- "traefik.http.routers.esn-frontend-login.rule=Path(/login)",我必须在浏览器中输入什么路径才能打开页面?
    【解决方案2】:

    我找到了问题

    基于此链接https://docs.traefik.io/routing/routers/#rule

    Backticks or Quotes?
    To set the value of a rule, use backticks ` or escaped double-quotes \".
    
    Single quotes ' are not accepted as values are Golang's String Literals.
    

    所以规则一定是

    "traefik.http.routers.app-contacts.rule==Path(`/contacts`)"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      • 2020-05-02
      相关资源
      最近更新 更多