Service names in multiple docker-compose projects locally

I have a local development tool which allows running multiple projects with traefik with domains like project1.mylocal.dev and project2.mylocal.dev.

Current stable using Traefik version 1.7 works as wanted.

I have one setup for the "tool": docker-compose.yml file which runs traefik, portainer and some other tools. Also a network for them.

Now when I'm making port to use Traefik 2, I have following problem:

Example:

I have 2 similar projects running with Nginx, PHP-FPM and MySQL with their own docker-compose.yml files and services attached to network where Traefik is running (external:true).

MySQL database

  • service name is "db"
  • container name is "project1-db" or "project2-db"

PHP-FPM

  • service name is "php"
  • container name is "project1-php" or "project2-php"
  • PHP connects to database with hostname "db" so the servicename of

Nginx will have Traefik labels to match local development domain. This works.

  • service name is "app"
  • container name is "project1-app" or "project2-app"
  • it has nginx configuration which says PHP is handled by service "php"

Problem with Traefik 2 is this:

  • nginx will connect to "php" service and that can now be either "project1-php" or "project2-php"
  • php will connect to "db" service and that can now be either "project1-db" or "project2-db"

With Traefik 1 they connect only to service in their own project. If I use container_name as host, it will connect to right container but then I need to have explicit conf files in every project (not good).

If I don't connect these services to shared network which traefik is used I get gateway errors (timeouts).
If I add internal network to project addition to shared networks I get gateway errors.
Traefik dashboard shows all is good.

Something related I think:

Labels in project docker-compose.yml need to have unique router names "system wide"?
"traefik.http.routers.${COMPOSE_PROJECT_NAME}-nginx.rule=Host({APP_HOST}`)"` instead of: `"traefik.http.routers.app.rule=Host(`{APP_HOST})" ??

It seems that if using shared Traefik, project docker-compose.yml files everything should be uniquely named?

2 Likes

Hello,

yes: routers, services, and middlewares must have unique name.

I got the thing working: I needed explicitly declare what is the network with label traefik.docker.network:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-app.entrypoints=https"
      - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-app.rule=Host(`project1.mylocal.dev`)"
      - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-app.tls=true"
      - "traefik.docker.network=shared-network-with-traefik"
    networks:
      - default
      - shared-network-with-traefik

Without the added label, Traefik routed the traffic sometimes to ip address from default network (in the project).

1 Like

hello

Can you please provide me with a copy of your codes if possible ?
I am having the same issue with traefik. By using ip the page load correctly but when I use url sometime 1 app loads but not the other.

I get Gateway Timeout

In my case I am using apache instead of nginx

1 Like

Hi,

Check branch 2.x on our repo: https://github.com/druidfi/stonehenge/tree/2.x

1 Like

I'm trying to do the same thing as you and have been unsuccessful... Getting cross talk between docker-compose projects and it is hard to debug.

If I add the traefik.docker.network name, then I get logs say it skips container because field not found (doesn't quite make sense to me):

time="2021-03-24T11:05:58Z" level=error msg="Skip container service-COMPOSE_PROJECT_NAME: field not found, node: network:{NETWORK}" providerName=docker

Anyway, your networks field shows the network that is local to the docker-compose file. Wouldn't it be, according to your example:

networks:
  shared-network-with-traefik:
    external:
      name: something-else

And something-else would also be added externally in the main networking field of traefik's docker-compose? Currently it seems shared-network-with-traefik is the name of the network that is local to that project's docker-compose file...

Also, any other progress on getting total separation & concurrent use of multiple docker-compose files w/ 1 traefik instance - would be very useful to hear about :slight_smile:
Thanks!

NOTE: variable names in log output are evaluated correctly.

1 Like

Where is treafik getting that container name from (in the error message)?
Here are my other labels, per service:

    labels:
      - "traefik.enable=true"
#      - "traefik.docker.network:${NETWORK}"
#      - "traefik.port=2000"
      - "traefik.http.routers.app-$COMPOSE_PROJECT_NAME.rule=Host(`${WWW_VHOST}`,`${WWW_VHOST_WWW}`)"
      - "traefik.http.routers.app-$COMPOSE_PROJECT_NAME.entrypoints=websecure"
      - "traefik.http.routers.app-$COMPOSE_PROJECT_NAME.middlewares=comp-${COMPOSE_PROJECT_NAME}"
      - "traefik.http.routers.app-$COMPOSE_PROJECT_NAME.tls=true"
      - "traefik.http.routers.app-$COMPOSE_PROJECT_NAME.tls.certresolver=le"
      - "traefik.http.middlewares.comp-$COMPOSE_PROJECT_NAME.compress=true"
      - "traefik.http.services.app-$COMPOSE_PROJECT_NAME.loadbalancer.server.port=2000"

@ldez I think this is a clue for me:

logger.Errorf("Skip container %s: %v", getServiceName(dData), err)

So, the service name in docker container inspect app-${COMPOSE_PROJECT_NAME} is actually "app" - so maybe traefik is looking in the wrong place and not actually compatible with DOCKER_COMPOSE_NAME usage...

Yes, it seems this "field not found" error - which isn't very helpful - is the reason why treafik.docker.network isn't working... Perhaps the error message is just wrong because those are not the container names, but perhaps the service names. I think docker does servicename-$COMPOSE_PROJECT_NAME when COMPOSE_PROJECT_NAME is in use... Pretty confused.

@back-2-95 aren't your services seen as servicename-$COMPOSE_PROJECT_NAME by traefik? And for some reason treafik calls them "container name" in the error which isn't actually true (verified by changing service name and seeing traefik's error change). The COMPOSE_PROJECT_NAME is always appended to the service name in the traefik log, but I don't know if this is the reason I get this error when adding traefik.docker.network per service.

Also @back-2-95, it seems you only have one traefik network anyway. Does that mean you're launching multiple instances of traefik? Like one per docker compose project? I don't get why you have ${PREFIX} var, but it only evaluates to one thing:

  traefik:
    image: "traefik:v${TRAEFIK_VERSION}"
    container_name: "${PREFIX}-traefik"
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    command: |-
      --providers.docker.network="${PREFIX}-network"

++++++++++++++++

Figured it out! I had - "traefik.docker.network:${NETWORK}"
instead of
- "traefik.docker.network=${NETWORK}"
in a few places. Would be great if that syntax failed instead of being sent to traefik & misinterpreted.

Now I just need to figure out how to get traefik docker labels to work during docker-compose build time:

The following does not work:

    app:
      container_name: "app-${COMPOSE_PROJECT_NAME}"
      image: "app"
      restart: always
      build:
        context: .
        network: "${NETWORK}"
        args:
         - project=$COMPOSE_PROJECT_NAME
 #      labels:
 #        - "traefik.enable=true"
 #        - "traefik.port=3000"
 #        - "traefik.docker.network=${NETWORK}"

Those layers get built into the image and do not supply treafik with the information it needs.