docker_logo.png

Спочатку використовував звичайний образ nginx, який биндил на 80 (або будь-який інший) порт і дивився сайт з браузера урлом http://127.0.0.1[:8080]. Потім прочитав про проксі і став використовувати Traefik, але тільки для контейнерів, які запускалися з одного docker-compose.yml файлу і тільки в одній віртуальній мережі. І вже з гарними урлами, типу http://mywebsite.in-docker.localhost/.

Несподівано постало завдання, щоб два сайти на локалці крутилися і могли між собою спілкуватися, запити посилати і дізнаватися як справи. Ідея клонування контейнерів у docker-compose мені не подобається. Можна було б запустити nginx-1+php-1, nginx-2+php-2, дати їм різні урли. І тому що вони в одній віртуальній мережі (default) те й бачили б один одного. Але що, якщо треба додати ще кілька сайтів? Вже негарно виходить… php-1, php-2, php-3, php-4…

Вирішенням цієї проблеми є створення однієї спільної віртуальної мережі та спільного Traefik для всіх сайтів.

Створюємо файл docker-compose.traefik.yml

version: "3"

services:
  traefik:
    image: traefik
    container_name: "my-traefik"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - ./traefik.toml:/etc/traefik/traefik.toml:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro

networks:
  default:
    external:
      name: common-traefik

80 порт для всіх сайтів, 8080 для дашбоарду самого траєфіка.

Важливо! файл /images-traefik/traefik.toml в ньому даємо команду відображати дашборду і яку мережу моніторити під докером.

[api]
    dashboard = true
    insecure = true

[providers.docker]
    watch = true
    network = "common-traefik"   

Далі створюємо композ докер для наших сайтів клонів. docker-compose.drupal8.yml

version: '3'
services:
  php-fpm:
    image: php:7.4-fpm-alpine
    container_name: "${PROJECT_NAME}-php-fpm"
    volumes:
      - ../${PROJECT_NAME}:/drupal
    links:
      - mariadb
    labels:
      - "traefik.enable=false"
    networks:
      - default
      - project-network

  web:
    image: nginx:alpine
    container_name: "${PROJECT_NAME}-web"
    expose:
      - '80'
    volumes:
      - ../${PROJECT_NAME}:/drupal
    environment:
      - SERVER_NAME=${PROJECT_NAME}.my-docker.localhost
    links:
      - php-fpm
    labels:
      - traefik.http.routers.${PROJECT_NAME}.rule=Host(`${PROJECT_NAME}.my-docker.localhost`)
    depends_on:
      - php-fpm
    networks:
      - default
      - project-network

  mariadb:
    image: mariadb:10.3
    container_name: "${PROJECT_NAME}-sql"
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
      MYSQL_DATABASE: 'drupal8'
      MYSQL_USER: 'drupal8'
      MYSQL_PASSWORD: 'drupal8'
    command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--default-authentication-plugin=mysql_native_password']
    labels:
      - "traefik.enable=false"
    cap_add:
      - SYS_NICE
    volumes:
      - db:/var/lib/mysql
    networks:
      - project-network


volumes:
  db:

networks:
  default:
    external:
      name: common-traefik

  project-network:
    name: ${PROJECT_NAME}-network
    internal: true

Він спрощений, наскільки можна, у вас буде складніше. Зверніть увагу на опис віртуальних мереж внизу файлу. А саме зовнішня мережа common-traefik.

У файлі можна помітити ${PROJECT_NAME} – для кожного сайту будуть свої значення.

Як використовувати різні env файли для інстансів, я опишу в наступній статті.

Зверніть увагу на лейби – прописуються правила для траєфіка, і під якими урлами контейнер буде доступний з браузера на локалці.

- traefik.http.routers.${PROJECT_NAME}.rule=Host(`${PROJECT_NAME}.my-docker.localhost`)

Перед запуском траєфіка необхідно створити мережу

$ docker network create \
  --driver=bridge \
  --attachable \
  --internal=false \
  common-traefik

Перевіряємо, що мережа створена комнадою. У списку має бути мережа common-traefik

$ docker network ls

Загалом, запускаємо спочатку наш докер із траєфіком

$ docker-compose --project-name my-traefik --file ./docker-compose.traefik.yml up -d –build

і після того, як все завантажилося і запустилося, можна перевірити список запущених контейнерів.

$ docker ps

Запускаємо вебсайти

$ export PROJECT_NAME=website1;docker-compose --project-name ${PROJECT_NAME}--file ./docker-compose.drupal8.yml up -d –build
$ export PROJECT_NAME=website2;docker-compose --project-name ${PROJECT_NAME}--file ./docker-compose.drupal8.yml up -d –build

 

чудово. Що далі?

Перевірити, що дашборда траєфіка працює

http://127.0.0.1:8080/dashboard

Зайти в роути та подивитися на виявлені інстанси

http://127.0.0.1:8080/dashboard#/http/routers

і зайти по урлам сайту перевірити, що все працює

http://website1.my-docker.localhost/

http://website2.my-docker.localhost/

вимкнути контейнери

$ export PROJECT_NAME=website1;docker-compose --project-name ${PROJECT_NAME} --file ./docker-compose.drupal8.yml down
$ export PROJECT_NAME=website2;docker-compose --project-name ${PROJECT_NAME} --file ./docker-compose.drupal8.yml down
$ docker-compose --project-name my-traefik --file ./docker-compose.traefik.yml down

Звичайно, писати це все в консолі чи копіювати-вставити не зручно. В іншій статті покажу Makefile.

Таким чином, нам вдалося запустити два сайти, які використовують однакові за контентом і налаштування контейнери, з одного docker-compose файлу! Даний приклад використовується тільки для локальної розробки, тому на сервері в продакшні потрібні додаткові налаштування безпеки.

код можна завантажити тут https://github.com/onesixromcom/docker_traefik_multiple