I'm currently trying to run multiple instances of the same docker-compose file.
Each instance have a traefik service which should only listen for a given host.
I want to have only one docker-compose file, and all params are stored in env variables. Each instance is run in its own directory.
In order to do that, i want traefik to redirect the http traffic (80 and 443) to my internal network, with the ability to define custom ports (eg 81 and 444) to avoid conflict when running more than one instance.
I try to use traefik constraint and port mapping, but if i put other values than 80, 443, and 8080 to TRAEFIK_XXX vars, no traffic seem to reach my containers.
Here is the relevant part of my docker-compose file :
version: "3.9"
services:
traefik:
image: traefik:2.10.7
restart: always
networks:
- traefik
ports:
- "${TRAEFIK_HTTP_PORT}:80"
- "${TRAEFIK_HTTPS_PORT}:443"
- "${TRAEFIK_API_PORT}:8080"
command:
# provider
- "--providers.docker=true"
# log
- "--log.level=DEBUG"
# entry points
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
# for https
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# constraint
- "--providers.docker.constraints=Label(`traefik.constraint-label`, `traefik_${INSTANCE_ID}`)"
labels:
- "traefik.enable=true"
- "traefik.constraint-label=traefik_${INSTANCE_ID}"
- "traefik.docker.network=traefik_${INSTANCE_ID}"
- "traefik.http.routers.traefik.rule=Host(`traefik.${BASE_DOMAIN}`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=myresolver"
strapi:
build:
context: ./strapi
dockerfile: Dockerfile.prod
restart: unless-stopped
hostname: "strapi.${BASE_DOMAIN}"
depends_on:
- postgres
- redis
networks:
- samplstrap
- traefik
ports:
- "${STRAPI_PORT}:1337"
labels:
- "traefik.enable=true"
- "traefik.constraint-label=traefik_${INSTANCE_ID}"
- "traefik.docker.network=traefik_${INSTANCE_ID}"
- "traefik.http.services.strapi.loadbalancer.server.port=1337"
- "traefik.http.routers.strapi.rule=Host(`strapi.${BASE_DOMAIN}`)"
- "traefik.http.routers.strapi.entrypoints=websecure"
- "traefik.http.routers.strapi.tls.certresolver=myresolver"
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.prod
restart: always
depends_on:
- strapi
networks:
- samplstrap
- traefik
volumes:
- frontend_node_modules:/app/frontend/node_modules
ports:
- "${FRONTEND_PORT}:3000"
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_${INSTANCE_ID}"
- "traefik.constraint-label=traefik_${INSTANCE_ID}"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
- "traefik.http.routers.frontend.rule=Host(`www.${BASE_DOMAIN}`, `${BASE_DOMAIN}`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=myresolver"
networks:
traefik:
external: true
name: traefik_${INSTANCE_ID}
samplstrap:
internal: true
Thanks !
A better solution for that setup is probably having one docker-compose file for Traefik and then another docker-compose file for all other services. Because only one Traefik container is needed and the other services are to be run as several instances.
My suggestions start with ###
in the code.
File to be used only in/for one directory/instance:
Filename: compose.traefik.yml
services:
traefik:
image: traefik:2.10.7
restart: always
networks:
- traefik
ports:
### Ports without variables, always like this
- "80:80"
- "443:443"
- "8080:8080"
### This needs to be added
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
# provider
- "--providers.docker=true"
# log
- "--log.level=DEBUG"
# entry points
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
# for https
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# constraint
### Remove this line
#- "--providers.docker.constraints=Label(`traefik.constraint-label`, `traefik_${INSTANCE_ID}`)"
labels:
- "traefik.enable=true"
### Remove this line
#- "traefik.constraint-label=traefik_${INSTANCE_ID}"
- "traefik.docker.network=traefik"
- "traefik.http.routers.traefik.rule=Host(`traefik.${BASE_DOMAIN}`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=myresolver"
networks:
traefik:
external: true
### Network name just 'traefik'
name: traefik
File to be used in/for several directories/instances:
Filename: compose.instance.yml
services:
strapi:
build:
context: ./strapi
dockerfile: Dockerfile.prod
restart: unless-stopped
hostname: "strapi.${BASE_DOMAIN}"
depends_on:
- postgres
- redis
networks:
- samplstrap
### Network name just 'traefik'
- traefik
### Remove this
#ports:
# - "${STRAPI_PORT}:1337"
labels:
- "traefik.enable=true"
### Remove this line
#- "traefik.constraint-label=traefik_${INSTANCE_ID}"
### Network name just 'traefik'
- "traefik.docker.network=traefik"
### Remove this line
#- "traefik.http.services.strapi.loadbalancer.server.port=1337"
- "traefik.http.routers.strapi.rule=Host(`strapi.${BASE_DOMAIN}`)"
- "traefik.http.routers.strapi.entrypoints=websecure"
- "traefik.http.routers.strapi.tls.certresolver=myresolver"
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.prod
restart: always
depends_on:
- strapi
networks:
- samplstrap
### Network name just 'traefik'
- traefik
volumes:
- frontend_node_modules:/app/frontend/node_modules
### Remove this
#ports:
#- "${FRONTEND_PORT}:3000"
labels:
- "traefik.enable=true"
### Network name just 'traefik'
- "traefik.docker.network=traefik"
### Remove this line
#- "traefik.constraint-label=traefik_${INSTANCE_ID}"
### Remove this line
#- "traefik.http.services.frontend.loadbalancer.server.port=3000"
- "traefik.http.routers.frontend.rule=Host(`www.${BASE_DOMAIN}`, `${BASE_DOMAIN}`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=myresolver"
networks:
traefik:
external: true
### Network name just 'traefik'
name: traefik
samplstrap:
internal: true
This answer is for making Traefik configuration work. Methods or ports for communication between strapi and frontend is not in the scope of this answer.