Сопоставление портов Docker-compose и traefik

В настоящее время я пытаюсь запустить несколько экземпляров одного и того же файла docker-compose.

У каждого экземпляра есть служба traefik, которая должна прослушивать только данный хост.

Я хочу иметь только один файл для создания докеров, и все параметры хранятся в переменных env. Каждый экземпляр запускается в своем собственном каталоге.

Для этого я хочу, чтобы traefik перенаправлял http-трафик (80 и 443) в мою внутреннюю сеть с возможностью определять собственные порты (например, 81 и 444), чтобы избежать конфликтов при запуске более одного экземпляра.

Я пытаюсь использовать ограничение traefik и сопоставление портов, но если я поставлю в переменные TRAEFIK_XXX другие значения, кроме 80, 443 и 8080, трафик, похоже, не достигнет моих контейнеров.

Вот соответствующая часть моего файла docker-compose:

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

Спасибо !

Что за конфликт?

Teemu Risikko 10.04.2024 22:01

1. Каков вывод docker logs -f traefik, когда - "--log.level=INFO" изменено на - "--log.level=DEBUG", а второй контейнер(ы) запускается в другом каталоге? 2. Как понять, что конфликт есть – каковы симптомы? 3. Логи всех остальных контейнеров тоже могут быть интересны, например docker logs -f strapi

Emil Carpenter 11.04.2024 11:52

Кажется, это не проблема конфликта, а мое непонимание того, как должно работать сопоставление портов. Я обновлю свой вопрос

lovis91 11.04.2024 13:12

я не получаю никаких проблем с журналом, используя log.level=INFO, HTTP-трафик просто не достигает моих контейнеров @EmilCarpenter

lovis91 11.04.2024 13:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Лучшим решением для этой настройки, вероятно, будет создание одного файла docker-compose для Traefik, а затем другого файла docker-compose для всех остальных служб. Потому что нужен только один контейнер Traefik, а остальные сервисы нужно запускать как несколько экземпляров.

Мои предложения начинаются с ### в коде.

Файл, который будет использоваться только в/для одного каталога/экземпляра:

Имя файла: 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

Файл, который будет использоваться в/для нескольких каталогов/экземпляров:

Имя файла: 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

Этот ответ предназначен для работы конфигурации Traefik. Методы или порты для связи между Strapi и интерфейсом не входят в рамки этого ответа.

у меня есть этот журнал ошибок, когда я проверяю контейнер traefik: «Ошибка подключения поставщика. Невозможно подключиться к демону Docker в unix:///var/run/docker.sock. Демон Docker запущен?, повторная попытка в 1.268030353s»

lovis91 11.04.2024 15:50

Попробуйте добавить volumes: - /var/run/docker.sock:/var/run/docker.sock:ro под services: traefik:.

Emil Carpenter 11.04.2024 16:19

Да, я забыл откатить некоторые строки, теперь все работает как положено, большое спасибо за ваше время и советы!

lovis91 11.04.2024 17:13

Другие вопросы по теме