Use Traefik with Docker Compose to serve 2 services on the same host but different routes

I have 2 frontend apps, both are served by Nginx in port 80

  1. app-login
  2. app-contacts

I'm trying to configure Traefik with Docker Compose to achieve this:

  • Both apps are served on the same host (for example abc.com or localhost:4000)
  • app-login will be accessed from localhost:4000/login (or abc.com/login)
  • app-contacts will be accessed from localhost:4000/contacts (or abc.com/contacts)

But the problem is: it doesn't work with what I did so far.

Below are 2 Dockerfile of 2 apps and the docker-compose.yml

app-login Dockerfile:

# 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: (a bit more complicated but it's just similar to login app)

### 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
      - "81:81"
      # 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)"

I have to run Traefik on port 81 because when I use port 80, when running docker-compose up -d, it will throw an error said port 80 is being used.

Not sure where I did wrong.

I searched Google and somewhere I see that people are using https://www.getambassador.io/ with this stack, but I don't know how to configure it either.

Thank you.

did you ever get your issue resolved?

Not yet, but check my question on Reddit. At least there is someone tried to help there: https://www.reddit.com/r/Traefik/comments/i7nn6m/multi_path_routing_to_1_host_causes_cssjsimages