Multiple docker-compose Treafik instances

Hi,
my goal is to run multiple instances of a docker-compose file with different entrypoint ports. I only want to expose this one port which serves both my backend and frontend.

For this I created following docker-compose.yml:

version: '3.8'

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.4
    # Enables the web UI and tells Traefik to listen to docker
    command:
      # Traefik will listen on port 8080 by default for API request.
      - '--api.insecure=true'
      # Enabling docker provider
      - '--providers.docker'
      # Do not expose containers unless explicitly told so
      - '--providers.docker.exposedbydefault=false'
      - '--entryPoints.${PORT}-web.address=:${PORT}'
    ports:
      # The HTTP port
      - ${PORT}:${PORT}
      # The Web UI (enabled by --api.insecure=true)
      # - '8082:8080'
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

  postgres:
    image: postgres:13.2
    environment:
      - POSTGRES_USER=oip
      - POSTGRES_PASSWORD=
      - POSTGRES_HOST_AUTH_METHOD=trust

  jhipster:
    build: ./jhipster
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/backend
    # ports:
    # - 8080:8080
    depends_on:
      - postgres
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.port-${PORT}-jhipster.rule=PathPrefix(`/api`)'
      - 'traefik.http.routers.port-${PORT}-jhipster.entrypoints=${PORT}-web'

  frontend:
    build: ./frontend
    # ports:
    # - 3000:3000
    depends_on:
      - jhipster
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.port-${PORT}-frontend.rule=PathPrefix(`/`)'
      - 'traefik.http.routers.port-${PORT}-frontend.entrypoints=${PORT}-web'

I run an instance like this:

PORT=50777 COMPOSE_PROJECT_NAME=PRO777 docker-compose up

To get multiple instances of this docker compose to run I had to parameterize some of the service names so they don't clash within traefik. Didn't find a better way to get this to start.

It sort of works but the instances show following errors: reverse-proxy_1 | time="2021-07-25T18:46:02Z" level=error msg="entryPoint \"50777-web\" doesn't exist" routerName=port-50777-jhipster@docker entryPointName=50777-web
And also in the dashboard always the services of other instances are shown as failed.

Is there a way to isolate the the traefik instances? Like one traefik per docker-compose which does not know anything about the other running ones?

Thanks in advance.

You will be interested in constraints

Traefik will filter to those containers that match the contraint, that should eliminate the need to parametize the service names too.

As to why your entrypoint does not exist I would start by inspecting the container and see what is there for the command section.

1 Like

Thanks. This looks like what I need, the docs about that feature are pretty short though. I'll try to figure it out.

Not sure if I explained my error correctly. For the next screenshots I started the docker-compose two times, once with the port 50666 and once with 50777 and also changed the Web UI port nubmers so that I can view both at the same time.
This is how the view of the instance with port 50666 looks:

This is the Web UI of the one with port 50777:

What "command section" do you mean exactly?

I was interested in your entrypoint error, but having the two running on the same host without a constraint, that make sense that that error appears.

Let us know how you progress. I can put together an example if you need one.

Thanks again @cakiwi for the hint. I got it to work. For future reference, this is the working config using constrains:

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.4
    # Enables the web UI and tells Traefik to listen to docker
    command:
      # Enabling docker provider
      - '--providers.docker'
      # Do not expose containers unless explicitly told so
      - '--providers.docker.exposedbydefault=false'
      - '--entryPoints.${PORT}-web.address=:${PORT}'
      - '--providers.docker.constraints=Label(`custom.label`,`${COMPOSE_PROJECT_NAME}`)'
    ports:
      # The HTTP port
      - ${PORT}:${PORT}
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

  postgres:
    image: postgres:13.2
    environment:
      - POSTGRES_USER=oip
      - POSTGRES_PASSWORD=
      - POSTGRES_HOST_AUTH_METHOD=trust
    labels:
      - 'custom.label=${COMPOSE_PROJECT_NAME}'

  jhipster:
    build: ./jhipster
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/backend
    depends_on:
      - postgres
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.jhipster.rule=PathPrefix(`/api`)'
      - 'custom.label=${COMPOSE_PROJECT_NAME}'

  frontend:
    build: ./frontend
    depends_on:
      - jhipster
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.frontend.rule=PathPrefix(`/`)'
      - 'custom.label=${COMPOSE_PROJECT_NAME}'
1 Like