Кластер onlyoffice в docker

Автор George, Май 16, 2026, 02:41

« назад - далее »

George

Шаг 1: Развертывание GlusterFS на Ubuntu 24.041.1. Настройка hosts (Выполнить на ВСЕХ трех нодах)Откройте файл:bashsudo nano /etc/hosts
Используйте код с осторожностью.Добавьте ваши реальные IP-адреса в самый конец файла:text10.10.1.36 node1
10.10.1.37 node2
10.10.1.38 node3
Используйте код с осторожностью.1.2. Установка GlusterFS (Выполнить на ВСЕХ трех нодах)bashsudo apt update
sudo apt install -y glusterfs-server
sudo systemctl enable --now glusterd
Используйте код с осторожностью.1.3. Объединение нод в пул (Выполнить ТОЛЬКО на первой ноде — 10.10.1.36)Связываем сервера в единый кластер хранения:bashsudo gluster peer probe node2
sudo gluster peer probe node3
Используйте код с осторожностью.Убедиться, что ноды увидели друг друга, можно командой sudo gluster peer status.1.4. Подготовка директорий для данных (Выполнить на ВСЕХ трех нодах)Создаем локальную папку («кирпич»), где GlusterFS будет физически хранить реплики:bashsudo mkdir -p /gluster/brick1
Используйте код с осторожностью.1.5. Создание и запуск общего тома (Выполнить ТОЛЬКО на первой ноде — 10.10.1.36)Создаем распределенный том shared-vol с тройной репликацией:bashsudo gluster volume create shared-vol replica 3 node1:/gluster/brick1 node2:/gluster/brick1 node3:/gluster/brick1 force
sudo gluster volume start shared-vol
Используйте код с осторожностью.Статус созданного тома проверяется командой sudo gluster volume info.1.6. Монтирование тома (Выполнить на ВСЕХ трех нодах)Подключаем сетевое хранилище в систему в папку /mnt/gluster-storage.Создаем точку монтирования:bashsudo mkdir -p /mnt/gluster-storage
Используйте код с осторожностью.Открываем файл автозапуска дисков:bashsudo nano /etc/fstab
Используйте код с осторожностью.Добавляем в самый конец строку для автоматического монтирования (через localhost, чтобы при падении сети нода не зависала):textlocalhost:/shared-vol /mnt/gluster-storage glusterfs defaults,_netdev,x-systemd.automount 0 0
Используйте код с осторожностью.Монтируем прямо сейчас:bashsudo mount -a
Используйте код с осторожностью.1.7. Создание директории OnlyOffice (Выполнить на ЛЮБОЙ одной ноде)Создаем папку внутри Gluster и сразу выставляем права пользователя OnlyOffice (104:104):bashsudo mkdir -p /mnt/gluster-storage/onlyoffice_data
sudo chown -R 104:104 /mnt/gluster-storage/onlyoffice_data
Используйте код с осторожностью.Базовый уровень хранения на этих трех IP-адресах готов.
  •  

George

Шаг 2: Установка и настройка Galera Cluster на Ubuntu 24.042.1. Установка MariaDB (Выполнить на ВСЕХ трех нодах)Устанавливаем актуальную версию MariaDB Server:bashsudo apt update
sudo apt install -y mariadb-server mariadb-client
Используйте код с осторожностью.После установки сразу останавливаем службу, чтобы настроить конфигурацию кластера:bashsudo systemctl stop mariadb
Используйте код с осторожностью.2.2. Настройка конфигурации GaleraСоздаем чистый файл конфигурации кластера. Удалите всё содержимое старого файла, если оно там есть.На NODE 1 (10.10.1.36)bashsudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
Используйте код с осторожностью.Вставьте следующий конфиг:ini[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Настройки Galera
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cloudlife_galera"
wsrep_cluster_address="gcomm://10.10.1.36,10.10.1.37,10.10.1.38"
wsrep_sst_method=rsync

# Уникальные настройки для NODE 1
node_id=1
wsrep_node_address="10.10.1.36"
wsrep_node_name="node1"
Используйте код с осторожностью.На NODE 2 (10.10.1.37)bashsudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
Используйте код с осторожностью.Вставьте (изменен IP и имя ноды):ini[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Настройки Galera
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cloudlife_galera"
wsrep_cluster_address="gcomm://10.10.1.36,10.10.1.37,10.10.1.38"
wsrep_sst_method=rsync

# Уникальные настройки для NODE 2
node_id=2
wsrep_node_address="10.10.1.37"
wsrep_node_name="node2"
Используйте код с осторожностью.На NODE 3 (10.10.1.38)bashsudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
Используйте код с осторожностью.Вставьте (изменен IP и имя ноды):ini[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Настройки Galera
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cloudlife_galera"
wsrep_cluster_address="gcomm://10.10.1.36,10.10.1.37,10.10.1.38"
wsrep_sst_method=rsync

# Уникальные настройки для NODE 3
node_id=3
wsrep_node_address="10.10.1.38"
wsrep_node_name="node3"
Используйте код с осторожностью.2.3. Запуск кластера (Внимание, строгий порядок!)Кластер Galera нельзя запускать обычной командой systemctl start на первом сервере, так как ему не к кому подключаться. Первую ноду нужно «инициализировать».Шаг А: Инициализация на NODE 1 (10.10.1.36)Выполните специальную команду создания нового кластера:bashsudo galera_new_cluster
Используйте код с осторожностью.Чтобы проверить, что нода запустилась в режиме кластера, выполните:bashsudo mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
Используйте код с осторожностью.Вывод должен показать Value: 1.Шаг Б: Запуск на NODE 2 (10.10.1.37)Теперь, когда первая нода ждет подключений, запускаем вторую ноду в обычном режиме:bashsudo systemctl start mariadb
Используйте код с осторожностью.Она автоматически свяжется с первой нодой по rsync и заберет структуру. Проверяем размер кластера на любом из двух серверов: wsrep_cluster_size должен стать 2.Шаг В: Запуск на NODE 3 (10.10.1.38)Запускаем последнюю ноду:bashsudo systemctl start mariadb
sudo systemctl enable mariadb  # Добавляем в автозагрузку на будущее
Используйте код с осторожностью.Теперь на всех трех нодах wsrep_cluster_size должен показать 3. Кластер Galera успешно собран на чистой системе.2.4. Первичная безопасность и создание базы OnlyOfficeНа любой одной ноде запустите базовую настройку безопасности (задайте root-пароль, удалите анонимов):bashsudo mysql_secure_installation
Используйте код с осторожностью.Зайдите в консоль MySQL (mysql -u root -p) и создайте базу данных и пользователя, которые понадобятся OnlyOffice:sqlCREATE DATABASE onlyoffice CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'onlyoffice'@'%' IDENTIFIED BY 'SuperSecretDBPass';
GRANT ALL PRIVILEGES ON onlyoffice.* TO 'onlyoffice'@'%';
FLUSH PRIVILEGES;
Используйте код с осторожностью.Благодаря Galera, эта база мгновенно появится на остальных двух серверах.Жду команду. Как только Galera статус покажет размер 3 и база будет создана — пишите.Следующий Шаг 3: Инициализация Docker Swarm кластера на этих нодах и прокидывание "моста" из Docker во внешнюю Galera. Переходим?а ты не ошибся? не вот так должен быть конфиг? [mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

[galera]

# Настройки Galera
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cloudlife_galera"
wsrep_cluster_address="gcomm://10.10.1.36,10.10.1.37,10.10.1.38"
wsrep_sst_method=rsync

# Уникальные настройки для NODE 3
node_id=3
wsrep_node_address="10.10.1.38"
wsrep_node_name="node3"Вы правы, вынеся настройки в отдельную секцию [galera], вы сделали синтаксически более чистый и красивый конфиг. Но технической ошибки в моём варианте нет.Дело в том, как MariaDB внутри себя парсит конфигурационные файлы. Секция [galera] — это просто подгруппа (alias). Все переменные, начинающиеся с wsrep_, сервер MariaDB прекрасно понимает и считывает, даже если они находятся внутри основной секции [mysqld].Однако ваш вариант с явным разделением на [mysqld] и [galera] считается лучшей практикой (best practice), так как он гораздо легче читается человеком. Использовать нужно именно его.Единственный момент: в MariaDB параметр node_id не существует (он используется в MaxScale или MySQL Cluster). Для идентификации ноды в Galera используются параметры wsrep_node_address и wsrep_node_name. Строчку node_id=3 можно безопасно удалить, чтобы сервер не ругался в логи на неизвестную переменную.Итоговый идеальный конфиг для NODE 1 (10.10.1.36):ini[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cloudlife_galera"
wsrep_cluster_address="gcomm://10.10.1.36,10.10.1.37,10.10.1.38"
wsrep_sst_method=rsync

wsrep_node_address="10.10.1.36"
wsrep_node_name="node1"
Используйте код с осторожностью.(Для второй и третьей ноды просто меняем две последние строчки на их IP и имена node2/node3).Прописывайте эти конфиги, запускайте кластер через sudo galera_new_cluster на первой ноде и systemctl start mariadb на остальных
  •  

George

Шагу 3: Сборка кластера Docker Swarm и организация связи из контейнеров во внешнюю сеть хостов.Основная сложность здесь в том, что контейнеры OnlyOffice будут запущены внутри изолированной overlay-сети Docker, а MariaDB Galera работает прямо на операционной системе (на хосте). Нам нужно сделать так, чтобы контейнеры гарантированно достучались до IP-адресов хостов (10.10.1.36, 37, 38).Часть 1. Инициализация Docker Swarm кластераНам нужно объединить три ноды Ubuntu 24.04 в единый Swarm. Делать все три ноды Менеджерами (Managers) — идеальное решение для трехнодового кластера. Если упадет одна любая нода, оставшиеся две сохранят кворум и продолжат управлять стеком.3.1. Инициализация кластера (Выполнить ТОЛЬКО на NODE 1 — 10.10.1.36)Запускаем Swarm на первом сервере и явно указываем IP для межведомственной связи кластера:bashsudo docker swarm init --advertise-addr 10.10.1.36
Используйте код с осторожностью.В ответ команда выведет длинную строку подключения, которая выглядит примерно так:docker swarm join --token SWMTKN-1-XXXXX 10.10.1.36:23773.2. Получение токена для Менеджеров (Выполнить ТОЛЬКО на NODE 1)По умолчанию Docker генерирует токен для добавления Воркеров (рабочих нод). Но нам нужны Менеджеры. Получите правильную команду подключения:bashsudo docker swarm join-token manager
Используйте код с осторожностью.Скопируйте сгенерированную команду docker swarm join --token ... из вывода.3.3. Подключение остальных нод (Выполнить на NODE 2 и NODE 3)Вставьте скопированную команду на втором (10.10.1.37) и третьем (10.10.1.38) серверах:bashsudo docker swarm join --token SWMTKN-1-ПРАВИЛЬНЫЙ_ТОКЕН_МЕНЕДЖЕРА 10.10.1.36:2377
Используйте код с осторожностью.Терминал должен ответить: This node has joined a swarm as a manager.3.4. Проверка статуса кластера (Выполнить на ЛЮБОЙ ноде)bashsudo docker node ls
Используйте код с осторожностью.Вы должны увидеть список из трех нод. В колонке STATUS должно быть Ready, а в колонке AVAILABILITY — Active. Все три должны иметь статус Leader или Reachable в графе MANAGER STATUS.Часть 2. Прокидывание «моста» во внешнюю GaleraВ Docker Swarm контейнеры по умолчанию изолированы. Чтобы OnlyOffice мог достучаться до Galera на хосте, мы создадим общую overlay-сеть для стека с включенным параметром attachable.3.5. Создание overlay-сети (Выполнить ТОЛЬКО на NODE 1)Создаем сеть, в которой будут жить Caddy, OnlyOffice, Redis и RabbitMQ:bashsudo docker network create --driver overlay --attachable cloudlife_net
Используйте код с осторожностью.3.6. Проверка доступности хоста из сети Docker (Важный тест безопасности)Контейнеры внутри cloudlife_net по умолчанию могут достучаться до хост-машин по их реальным IP-адресам, ЕСЛИ это не заблокировано файрволом Ubuntu 24.04 (UFW).Давайте создадим временный контейнер в нашей новой сети и попробуем проверить доступ к порту MariaDB (3306) на хосте:bashsudo docker run --rm --network cloudlife_net alpine nc -zv 10.10.1.36 3306
Используйте код с осторожностью.Если вывод: 10.10.1.36 (10.10.1.36:3306) open — Всё супер! Связь есть, мост работает.Если выдает ошибку или зависает: Файрволл ufw на Ubuntu блокирует запросы из подсети Docker. В этом случае выполните на ВСЕХ трех нодах команду, разрешающую подсетям Docker доступ к хосту:bashsudo ufw allow from 10.0.0.0/8 to any port 3306 proto tcp
Используйте код с осторожностью.(И повторите тест с nc -zv еще раз, чтобы убедиться в успехе).Docker Swarm собран в отказоустойчивый треугольник, сеть настроена, доступ к внешней Galera проверен.Проверьте, прошел ли тест nc -zv к порту 3306.
  •  

George

#3
Шаг 5. Подготовка остальных каталогов в GlusterFS (Выполнить на любой ОДНОЙ ноде)Помимо документов, нам нужно создать папки для баз данных Redis, а также для конфигурации и SSL-сертификатов Caddy.Создаем папки для Redis и Caddy:bashsudo mkdir -p /mnt/gluster-storage/onlyoffice_redis_data
sudo mkdir -p /mnt/gluster-storage/caddy_data
sudo mkdir -p /mnt/gluster-storage/caddy_config
Используйте код с осторожностью.Назначаем права для Redis:В официальном alpine-образе Redis работает под пользователем redis (UID 999, GID 999).bashsudo chown -R 999:999 /mnt/gluster-storage/onlyoffice_redis_data
Используйте код с осторожностью.Назначаем права для Caddy:Caddy в контейнере работает от пользователя caddy (UID 1000, GID 1000).bashsudo chown -R 1000:1000 /mnt/gluster-storage/caddy_data
sudo chown -R 1000:1000 /mnt/gluster-storage/caddy_config
Используйте код с осторожностью.теперь права распределены изолированно и безопасно.Шаг 6. Создание отказоустойчивого CaddyfileТак как Caddy у нас работает в режиме global (на всех 3 нодах), они будут одновременно читать один файл конфигурации из GlusterFS. Благодаря тому, что папка /data (где Caddy хранит SSL-сертификаты Let's Encrypt) тоже вынесена в GlusterFS, ноды Caddy будут делить сертификаты между собой автоматически и не заблокируют лимиты Let's Encrypt.Создайте файл конфигурации:bashsudo nano /mnt/gluster-storage/Caddyfile
Используйте код с осторожностью.Вставьте в него следующий продакшен-конфиг. Я добавил туда оптимизацию для работы 1000 человек, долгоживущие веб-сокеты и проксирование на ваш новый кластер OnlyOffice:caddy# --- НАСТРОЙКИ КЛАССТЕРА ONLYOFFICE ---
docs.cloud-life.site {
    # Проксируем запросы на встроенный балансировщик Swarm
    # Имя 'hub_onlyoffice' сформировано из имени стека и имени сервиса
    reverse_proxy hub_onlyoffice:80 {
        # Передаем реальные заголовки, чтобы OnlyOffice понимал, откуда идет трафик
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}
       
        # Настройки таймаутов для 1000 пользователей (чтобы тяжелые документы не отваливались при открытии)
        transport http {
            dial_timeout 10s
            read_buffer_size 4096
        }
    }

    # Включаем сжатие ответов (ускоряет загрузку интерфейса редактора у клиентов)
    encode gzip zstd
}

# --- ПРОВЕРКА ЖИВУЧЕСТИ ДЛЯ ВНЕШНЕГО БАЛАНСИРОВЩИКА (Если используете HAProxy/Keepalived) ---
:8080 {
    respond /health "OK" 200
}


Шагу 4: Создание конфигурации продакшен-стека.



Мы собираем всё в один файл docker-compose.yml, который развернет Caddy, OnlyOffice, Redis и RabbitMQ на всех трех новых нодах Ubuntu 24.04.Поскольку Galera работает на хостах, мы настроим OnlyOffice на отказоустойчивое циклическое подключение. Мы передадим ему IP-адреса всех трех серверов (10.10.1.36, 10.10.1.37, 10.10.1.38). Если одна нода базы данных упадет, OnlyOffice автоматически переключится на выжившую.Настройка параметров лимитов на хостах (Выполнить на ВСЕХ 3 нодах)Перед запуском OnlyOffice на 1000 человек нужно увеличить лимиты операционной системы на максимальное количество открытых файлов (иначе пользователи упрутся в системный потолок):bashsudo sysctl -w fs.file-max=100000
Используйте код с осторожностью.(Чтобы сохранить настройку после перезагрузки, добавьте строку fs.file-max = 100000 в конец файла /etc/sysctl.conf).Создание файла prod-stack.ymlСоздайте на мастер-ноде файл конфигурации стека:bashnano prod-stack.yml
Используйте код с осторожностью.Вставьте в него следующий продакшен-конфиг:yamlversion: '3.8'

services:

  # --- ФРОНТЕНД / ПРОКСИ (ЗАПУЩЕН НА КАЖДОЙ НОДЕ) ---
  caddy:
    image: caddy:latest
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /mnt/gluster-storage/Caddyfile:/etc/caddy/Caddyfile
      - /mnt/gluster-storage/caddy_data:/data
      - /mnt/gluster-storage/caddy_config:/config
    networks:
      - cloudlife_net
    deploy:
      mode: global
      restart_policy:
        condition: on-failure

  # --- ОЧЕРЕДЬ ЗАДАЧ ДЛЯ ONLYOFFICE ---
  onlyoffice-rabbitmq:
    image: rabbitmq:3-management-alpine
    environment:
      - RABBITMQ_DEFAULT_USER=onlyoffice
      - RABBITMQ_DEFAULT_PASS=SuperSecretRabbitPass  # Используйте ваш пароль
    networks:
      - cloudlife_net
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure

  # --- КЭШ И КООРДИНАЦИЯ СЕССИЙ РЕДАКТИРОВАНИЯ ---
  onlyoffice-redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - /mnt/gluster-storage/onlyoffice_redis_data:/data
    networks:
      - cloudlife_net
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure

  # --- КЛАССТЕР ONLYOFFICE DOCUMENT SERVER ---
  onlyoffice:
    image: onlyoffice/documentserver:latest
    environment:
      - JWT_ENABLED=true
      - JWT_SECRET=3e4b7f484b9304066de217c5315f586f
      - JWT_HEADER=AuthorizationJwt
      - USE_UNAUTHORIZED_STORAGE=true
     
      # Подключение к внешней распределенной Galera (Указываем все три IP хостов через запятую)
      - DB_TYPE=mysql
      - DB_HOST=10.10.1.36,10.10.1.37,10.10.1.38
      - DB_PORT=3306
      - DB_NAME=onlyoffice
      - DB_USER=onlyoffice
      - DB_PASSWORD=SuperSecretDBPass               # Пароль из Шага 2
     
      # Подключение к брокеру сообщений Swarm
      - AMQP_URI=amqp://onlyoffice:SuperSecretRabbitPass@onlyoffice-rabbitmq:5672/%2f
     
      # Подключение к кэшу Swarm
      - REDIS_SERVER_HOST=onlyoffice-redis
      - REDIS_SERVER_PORT=6379
    volumes:
      - /mnt/gluster-storage/onlyoffice_data:/var/www/onlyoffice/Data
    networks:
      - cloudlife_net
    deploy:
      mode: global  # Разворачиваем OnlyOffice на ВСЕ 3 ноды параллельно!
      resources:
        limits:
          memory: 4G # Запас памяти для 1000 активных пользователей
      update_config:
        parallelism: 1
        order: stop-first
        delay: 10s

networks:
  cloudlife_net:
    external: true  # Используем созданную нами на Шаге 3 сеть attachable
Используйте код с осторожностью.Запуск стекаЗапустите деплой созданной конфигурации (назовем стек hub, чтобы имена сервисов совпадали с вашими логами):bashsudo docker stack deploy -c prod-stack.yml hub
Используйте код с осторожностью.Как проверить, что всё запустилось успешно?Проверьте статус развертывания контейнеров по всему кластеру:bashsudo docker stack ps hub
Используйте код с осторожностью.Посмотрите логи OnlyOffice, чтобы убедиться, что он успешно подключился к внешней Galera, Redis и RabbitMQ и не выдал ошибок инициализации структуры БД:bashsudo docker service logs hub_onlyoffice --tail 50
Используйте код с осторожностью.Сохраняйте файл и запускайте деплой.
  •  

George

Что делаем дальше?Теперь у вас полностью готовы:Сеть GlusterFS со всеми нужными каталогами и правами пользователей (Шаг 1 и Шаг 5).Внешний отказоустойчивый кластер Galera на хостах (Шаг 2).Инициализированный Docker Swarm и сеть cloudlife_net (Шаг 3).Конфигурационный файл Caddyfile (Шаг 6).Все компоненты собраны. Вы можете смело возвращаться к файлу prod-stack.yml из предыдущего сообщения и запускать команду:bashsudo docker stack deploy -c prod-stack.yml hub
Используйте код с осторожностью.Дайте знать, когда запустите команду деплоя. Нам останется выполнить финальную проверку: посмотреть, как hub_onlyoffice распределился по вашим новым трем нодам. Стек успешно стартовал?Error: adapting config using caddyfile: parsing caddyfile tokens for 'reverse_proxy': unrecognized subdirective read_buffer_size, at /etc/caddy/Caddyfile:13 какая-то директива не поддерживается  cat Caddyfile
# --- НАСТРОЙКИ КЛАССТЕРА ONLYOFFICE ---
docs.cloud-life.site {
    # Проксируем запросы на встроенный балансировщик Swarm
    # Имя 'hub_onlyoffice' сформировано из имени стека и имени сервиса
    reverse_proxy hub_onlyoffice:80 {
        # Передаем реальные заголовки, чтобы OnlyOffice понимал, откуда идет тра                                                                                                             фик
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}

        # Настройки таймаутов для 1000 пользователей (чтобы тяжелые документы не                                                                                                              отваливались при открытии)
        transport http {
            dial_timeout 10s
            read_buffer_size 4096
        }
    }

    # Включаем сжатие ответов (ускоряет загрузку интерфейса редактора у клиентов                                                                                                             )
    encode gzip zstd
}

# --- ПРОВЕРКА ЖИВУЧЕСТИ ДЛЯ ВНЕШНЕГО БАЛАНСИРОВЩИКА (Если используете HAProxy/K                                                                                                             eepalived) ---
:8080 {
    respond /health "OK" 200
}Моя ошибка. В Caddy внутри блока transport http директива read_buffer_size отсутствует в таком виде. Настройка буферов в Caddy управляется глобально или через другие механизмы, а для стабильности тяжелых соединений в transport http достаточно стандартных параметров таймаутов.Давайте уберем проблемную строку, чтобы Caddy успешно запустился.Исправленный вариант CaddyfileОткройте файл /mnt/gluster-storage/Caddyfile и замените блок transport http на этот (строка с ошибкой удалена):caddy# --- НАСТРОЙКИ КЛАССТЕРА ONLYOFFICE ---
docs.cloud-life.site {
    # Проксируем запросы на встроенный балансировщик Swarm
    # Имя 'hub_onlyoffice' сформировано из имени стека и имени сервиса
    reverse_proxy hub_onlyoffice:80 {
        # Передаем реальные заголовки, чтобы OnlyOffice понимал, откуда идет трафик
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}

        # Настройки таймаутов для стабильной работы под нагрузкой
        transport http {
            dial_timeout 10s
        }
    }

    # Включаем сжатие ответов (ускоряет загрузку интерфейса редактора у клиентов)
    encode gzip zstd
}

# --- ПРОВЕРКА ЖИВУЧЕСТИ ДЛЯ ВНЕШНЕГО БАЛАНСИРОВЩИКА (Если используете HAProxy/Keepalived) ---
:8080 {
    respond /health "OK" 200
}
Используйте код с осторожностью.Как применить изменения:После сохранения файла отправьте Caddy команду на перечитку конфига:bashdocker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) caddy reload --config /etc/caddy/Caddyfile
Используйте код с осторожностью.Конфигурация должна примениться без ошибок. Сообщите, если Caddy успешно запустился, и мы сможем проверить статус сервиса OnlyOffice через docker stack ps hub.root@onlyoffice-stack-1:/mnt/gluster-storage# docker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) caddy reload --config /etc/caddy/Caddyfile
2026/05/16 20:11:09.046 INFO    using config from file  {"file": "/etc/caddy/Caddyfile"}
2026/05/16 20:11:09.049 WARN    caddyfile       Unnecessary header_up X-Forwarded-Host: the reverse proxy's default behavior is to pass headers to the upstream
2026/05/16 20:11:09.049 WARN    caddyfile       Unnecessary header_up X-Forwarded-Proto: the reverse proxy's default behavior is to pass headers to the upstream
2026/05/16 20:11:09.052 INFO    adapted config to JSON  {"adapter": "caddyfile"}
2026/05/16 20:11:09.052 WARN    Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies    {"adapter": "caddyfile", "file": "/etc/caddy/Caddyfile", "line": 3}
root@onlyoffice-stack-1:/mnt/gluster-storage# давай поправим до конца, это все-таки продПрекрасный подход. В продакшене логи должны быть идеально чистыми, без предупреждений (WARN), чтобы в случае реальной аварии сразу заметить важные сообщения.Варнинги говорят о двух вещах:Современный Caddy по умолчанию сам передает заголовки X-Forwarded-Host и X-Forwarded-Proto на бэкенд. Дублировать их вручную больше не нужно.Файл конфигурации имеет неидеальные отступы/пробелы с точки зрения встроенного линтера Caddy.Давайте сделаем конфиг безупречным.Шаг 1. Идеальный Caddyfile без лишних опцийОткройте ваш файл /mnt/gluster-storage/Caddyfile и приведите его к следующему чистому виду:caddy# --- НАСТРОЙКИ КЛАССТЕРА ONLYOFFICE ---
docs.cloud-life.site {
   # Проксируем запросы на встроенный балансировщик Swarm
   reverse_proxy hub_onlyoffice:80 {
      # Настройки таймаутов для стабильной работы под нагрузкой
      transport http {
         dial_timeout 10s
      }
   }

   # Включаем сжатие ответов (ускоряет работу интерфейса)
   encode gzip zstd
}

# --- ПРОВЕРКА ЖИВУЧЕСТИ ДЛЯ ВНЕШНЕГО БАЛАНСИРОВЩИКА ---
:8080 {
   respond /health "OK" 200
}
Используйте код с осторожностью.Шаг 2. Автоматическое форматирование (убираем последний WARN)Чтобы у Caddy вообще не было претензий к синтаксису, выполните команду автоматического форматирования прямо через контейнер. Она исправит все табы и отступы в файле на GlusterFS:bashdocker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) caddy fmt --overwrite /etc/caddy/Caddyfile
Используйте код с осторожностью.Шаг 3. Финальная проверкаТеперь примените конфигурацию заново:bashdocker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) caddy reload --config /etc/caddy/Caddyfile
Используйте код с осторожностью.Теперь в выводе должны остаться только чистые строки INFO о том, что конфиг успешно адаптирован и применен. Никаких WARN быть не должно.Вывод стал чистым? Если да, давайте проверим, как чувствуют себя контейнеры OnlyOffice, командой docker stack ps hub — все три ноды успешно запустились?Error: reading config from file: open /etc/caddy/Caddyfile: stale file handleОшибка stale file handle (устаревший дескриптор файла) — это специфическая и очень частая проблема распределенной файловой системы GlusterFS.Она возникает, когда утилита caddy fmt --overwrite перезаписала файл с одной ноды, создав новый дескриптор (inode) в системе, а контейнер Caddy на другой ноде (или системный кэш) всё ещё пытается прочитать старый идентификатор файла, которого физически больше нет на диске.Поскольку GlusterFS потерял связь с этим конкретным файлом, обычный caddy reload не сработает, пока операционная система не обновит кэш тома.Как это исправить прямо сейчас (в прод-кластере)Шаг 1. Сброс кэша GlusterFS на нодах хостаЧтобы вылечить stale file handle, нужно заставить операционную систему перечитать содержимое сетевой папки. Выполните на всех трех нодах хоста команду принудительного обновления атрибутов каталога:bashsudo ls -la /mnt/gluster-storage/
Используйте код с осторожностью.(Простой вызов ls -la внутри общей папки заставляет GlusterFS синхронизировать индексы файлов по сети и чинит эту ошибку в 99% случаев).Шаг 2. Перезапуск сервиса Caddy (если ls не помог)Если контейнеры Caddy намертво «залипли» на старом дескрипторе файла и продолжают выдавать ошибку, самый быстрый и безопасный способ для Swarm — это заставить кластер поочередно пересоздать контейнеры Caddy (с нулевым простоем / Zero Downtime):bashsudo docker service update --force hub_caddy
Используйте код с осторожностью.Docker Swarm по очереди перезапустит Caddy на каждой ноде. Новые контейнеры гарантированно прочитают свежий Caddyfile с GlusterFS уже без ошибок.⚠️ Прод-совет на будущееУтилиты автоматического форматирования или редактирования (вроде sed -i или caddy fmt --overwrite), которые удаляют старый файл и создают на его месте новый с тем же именем, противопоказаны для использования напрямую внутри контейнеров поверх сетевых папок (GlusterFS/NFS).В будущем на продакшене меняйте Caddyfile классическим способом: отредактировали через nano /mnt/gluster-storage/Caddyfile на хосте -> сделали docker service update --force hub_caddy или caddy reload.
  •  

George

1. Распределенное хранилище: GlusterFSГде живет: Напрямую на операционной системе всех трех нод.Зачем нужно: Это наше «общее облачное подземелье». Оно объединяет локальные диски трех серверов в один виртуальный жесткий диск, примонтированный в /mnt/gluster-storage.Как работает: Когда Caddy сохраняет SSL-сертификат или пользователь открывает документ в OnlyOffice, файл физически записывается на GlusterFS. В ту же миллисекунду по сети этот файл дублируется на остальные два сервера. Если сервер №1 сгорит, сервер №2 и №3 имеют точную копию всех файлов и продолжают работу без потери данных.2. Сердце данных: Galera Cluster (MariaDB)Где живет: Напрямую на хостах Ubuntu (вне Docker, для максимальной стабильности и скорости).Зачем нужно: Хранит информацию о пользователях, активных сессиях редактирования, правах доступа и истории изменений документов.Как работает: В отличие от классической схемы «Мастер-Слейв» (где один сервер главный, а остальные только копируют), Galera — это кластер Multi-Master. Все три ноды базы данных абсолютно равноправны и активны. Мы прописали в OnlyOffice все три IP-адреса через запятую. Если «падает» база на первой ноде, OnlyOffice за доли секунды переключает свои SQL-запросы на вторую ноду. Никаких сбоев при открытии документов.3. Диспетчер задач: RabbitMQГде живет: Внутри Docker Swarm.Зачем нужно: Это брокер очередей сообщений. Когда 1000 человек одновременно печатают текст, отправляют комментарии или сохраняют файлы, OnlyOffice не может обрабатывать всё это мгновенно в один поток — сервер бы завис.Как работает: RabbitMQ принимает все действия пользователей (например: «Иван вставил картинку», «Петр нажал Сохранить») и выстраивает их в аккуратную очередь. Ноды OnlyOffice подходят к этой очереди и разбирают задачи по мере своих сил. Это защищает систему от перегрузки: даже если начнется дикий наплыв пользователей, RabbitMQ удержит удары, и серверы не упадут, а просто будут обрабатывать задачи последовательно.4. Оперативная память кластера: RedisГде живет: Внутри Docker Swarm.Зачем нужно: Самый критичный компонент для коллективной работы. Отвечает за кэширование и синхронизацию сессий «на лету».Как работает: Когда 5 человек одновременно редактируют один и тот же отчет, их изменения не пишутся на жесткий диск каждую секунду (это бы убило GlusterFS). Все правки, движения курсоров и выделения текста мгновенно улетают в Redis — сверхбыструю базу данных, работающую прямо в оперативной памяти. Из Redis эти правки мгновенно транслируются всем остальным редакторам. Именно благодаря Redis пользователи видят изменения друг друга в реальном времени без задержек.Как всё это работает вместе (Путь одного запроса):Пользователь заходит в Nextcloud и открывает документ report.docx.Запрос прилетает на Caddy (который запущен на всех серверах). Caddy понимает, что это запрос к OnlyOffice, и перенаправляет его внутрь Docker Swarm на сервис OnlyOffice.Встроенный балансировщик Docker Swarm выбирает наименее загруженную ноду OnlyOffice (например, на третьем сервере) и отдает запрос ей.Нода OnlyOffice идет в Galera Cluster, проверяет сессию, затем заглядывает в GlusterFS, считывает сам файл документа, кэширует его в Redis и открывает пользователю в браузере.Когда пользователь начинает печатать, RabbitMQ и Redis подхватывают его действия, координируя их с другими участниками, а после закрытия вкладки OnlyOffice собирает все правки из оперативной памяти и сохраняет финальный файл обратно в GlusterFS.Каждый элемент дублирует друг друга. Это классическая, взрослая Production-архитектура, которую используют крупные корпорации.
  •  

George

Статус 502 от Caddy означает, что сам веб-сервер Caddy работает отлично и защищает соединение по HTTPS, но он не может достучаться до контейнеров OnlyOffice внутри сети Docker Swarm.Плюс, обратите внимание на домен: в запросе вы проверяете docu.cloud-life.site, а в файле Caddyfile мы прописали docs.cloud-life.site [1].Давайте проведем быструю диагностику по шагам, чтобы найти, на каком этапе обрывается связь.Шаг 1. Проверяем доменное имя в CaddyfileЕсли вы планируете использовать именно docu.cloud-life.site, то Caddy сейчас просто не применяет правила проксирования к этому поддомену.Откройте Caddyfile:bashnano /mnt/gluster-storage/Caddyfile
Используйте код с осторожностью.Убедитесь, что имя домена совпадает с тем, что вы вводите в браузере (поменяйте docs на docu [1], если необходимо):caddydocu.cloud-life.site {
    reverse_proxy hub_onlyoffice:80 {
        transport http {
            dial_timeout 10s
        }
    }
    encode gzip zstd
}
Используйте код с осторожностью.Перечитайте конфиг Caddy [2]:bashdocker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) caddy reload --config /etc/caddy/Caddyfile
Используйте код с осторожностью.Шаг 2. Проверяем статус контейнеров OnlyOfficeНам нужно убедиться, что контейнеры OnlyOffice вообще запустились и не падают по кругу (например, из-за неверного пароля к базе данных).Выполните команду на менеджер-ноде:bashdocker stack ps hub
Используйте код с осторожностью.Что искать: В колонке CURRENT STATE у сервиса hub_onlyoffice должно быть написано Running ... X minutes ago.Если там написано Shutdown или Failed: Контейнер падает при старте. Переходите к Шагу 3.Шаг 3. Смотрим логи OnlyOffice (Ищем причину падения)Если контейнеры не могут запуститься, они пишут ошибку в логи. Давайте посмотрим последние 50 строк:bashdocker service logs hub_onlyoffice --tail 50
Используйте код с осторожностью.Частая проблема 1 (Connection refused к БД): OnlyOffice не может достучаться до вашей внешней Galera. Проверьте, разрешен ли доступ пользователю onlyoffice с IP-адресов подсети Docker (мы настраивали это через ufw allow в Шаге 3).Частая проблема 2 (Access denied для пользователя): Неверно указан пароль DB_PASSWORD или имя базы в файле prod-stack.yml.Шаг 4. Проверка связи изнутри CaddyЕсли OnlyOffice запущен (Running), но Caddy всё равно выдает 502, значит, они не видят друг друга внутри overlay-сети Docker.Зайдите внутрь контейнера Caddy и попробуйте сделать запрос к балансировщику OnlyOffice:bashdocker exec -it $(docker ps -q -f name=hub_caddy | head -n 1) wget -qO- http://hub_onlyoffice:80
Используйте код с осторожностью.Если вернет HTML-код (или ошибку 404/отказ, но связь построится) — сеть Docker исправна, дело было в домене из Шага 1.Если напишет bad address или зависнет по таймауту — контейнеры Caddy и OnlyOffice почему-то оказались в разных сетях.Выполните команду docker stack ps hub и проверьте домен. Что показывают логи OnlyOffice из Шага 3?нет, там docu. docs старый пока живетПонял вас, docs не трогаем, работаем со свежим docu.Раз домен в порядке, а Caddy выдает стабильный 502, значит, контейнеры OnlyOffice либо физически не запустились, либо не могут пройти внутренний тест самопроверки (Healthcheck) из-за проблем с подключением к нашей новой внешней Galera Cluster.Давайте вытащим логи OnlyOffice и посмотрим, на каком этапе спотыкается инициализация. Выполните команду на мастер-ноде:bashsudo docker service logs hub_onlyoffice --tail 100
Используйте код с осторожностью.На какие строки в логах нужно обратить внимание:Если видите Error: Connect ECONNREFUSED 10.10.1.36:3306OnlyOffice пытается подключиться к Galera на хосте, но операционная система Ubuntu сбрасывает соединение.Решение: Проверьте, что в /etc/mysql/mariadb.conf.d/60-galera.cnf на хостах действительно прописано bind-address = 0.0.0.0, а не 127.0.0.1.Если видите Access denied for user 'onlyoffice'@'10.0.X.X'Galera сбрасывает подключение, так как IP-адрес, с которого пришел контейнер (внутренний IP сети Docker Swarm, например 10.0.0.5), не совпадает с правилами прав в MySQL.Решение: Зайдите в консоль MariaDB на хосте и выполните проверку: SELECT user, host FROM mysql.user WHERE user='onlyoffice';. Убедитесь, что там стоит хост % (разрешено подключение с любых IP).Если видите Waiting for connection to rabbitmq... или redis...OnlyOffice не может связаться с соседними контейнерами очередей или кэша внутри Swarm. Это означает, что они упали или зависли.Выполните команду sudo docker service logs hub_onlyoffice --tail 100 и пришлите последние строки, где видна ошибка. Что именно мешает запуску?.0.ko0df57lfm5y@onlyoffice-stack-2    | Waiting for connection to the 10.10.1.36,10.10.1.37,10.10.1.38 host on port 3306
hub_onlyoffice.0.ko0df57lfm5y@onlyoffice-stack-2    | nc: getaddrinfo for host "10.10.1.36,10.10.1.37,10.10.1.38" port 3306: Name or service not known
hub_onlyoffice.0.ko0df57lfm5y@onlyoffice-stack-2    | Waiting for connection to the 10.10.1.36,10.10.1.37,10.10.1.38 host on port 3306
hub_onlyoffice.0.ko0df57lfm5y@onlyoffice-stack-2    | nc: getaddrinfo for host "10.10.1.36,10.10.1.37,10.10.1.38" port 3306: Name or service not known
hub_onlyoffice.0.ko0df57lfm5y@onlyoffice-stack-2    | Waiting for connection to the 10.10.1.36,10.10.1.37,10.10.1.38 host on port 3306
hub_onlyoffice.0.ko0df57lfm5y@onlyoffice-stack-2    | nc: getaddrinfo for host "10.10.1.36,10.10.1.37,10.10.1.38" port 3306: Name or service not known он эти перечисленные хосты считает одним, и не можнт достучаться. Мы можем добавить реверс-прокси (балансировщик)? я использую haproxy. но в данном случан не хочу обращаться к внешним серверам, чтоб все жило на этих 3-хОтличная диагностика! Вы абсолютно правы: встроенный скрипт инициализации OnlyOffice внутри контейнера банально не умеет парсить строку с запятыми через nc (netcat). Он воспринимает всю строку "10.10.1.36,10.10.1.37,10.10.1.38" как один монолитный некорректный адрес и уходит в бесконечный цикл ожидания.Разворачивать внешние серверы ради этого точно не нужно. Так как вы уже знакомы с HAProxy, мы поднимем его внутри самого Docker Swarm в виде легковесного отказоустойчивого балансировщика прямо на этих же трех нодах.HAProxy будет слушать внутри сети Docker и перенаправлять трафик на ваши внешние хосты Galera. Если одна из нод базы данных упадет, HAProxy сам переключит поток на живую.Шаг 1. Переделываем YAML-файл стека (prod-stack.yml)Мы добавляем в стек официальный сервис haproxy и прописываем для onlyoffice один единственный внутренний адрес балансировщика.Откройте ваш prod-stack.yml и внесите изменения:В секции onlyoffice замените параметры БД на одиночный хост:yaml      # Теперь указываем локальный балансировщик HAProxy внутри Swarm
      - DB_TYPE=mysql
      - DB_HOST=onlyoffice-db-balancer
      - DB_PORT=3306
      - DB_NAME=onlyoffice
      - DB_USER=onlyoffice
      - DB_PASSWORD=SuperSecretDBPass
Используйте код с осторожностью.В самый конец секции services: добавьте новый сервис HAProxy:yaml  # --- ВНУТРЕННИЙ БАЛАНСИРОВЩИК ДЛЯ GALERA CLUSTER ---
  onlyoffice-db-balancer:
    image: haproxy:2.8-alpine
    volumes:
      - /mnt/gluster-storage/haproxy:/usr/local/etc/haproxy:ro
    networks:
      - cloudlife_net
    deploy:
      mode: replicated
      replicas: 2 # Запускаем 2 копии для отказоустойчивости самого прокси
      restart_policy:
        condition: on-failure
Используйте код с осторожностью.Шаг 2. Создание конфигурации HAProxy на GlusterFSПоскольку папка /mnt/gluster-storage синхронизируется между всеми серверами, конфигурация балансировщика будет доступна всем его копиям.Создайте папку для конфига:bashsudo mkdir -p /mnt/gluster-storage/haproxy
Используйте код с осторожностью.Создайте файл конфигурации:bashsudo nano /mnt/gluster-storage/haproxy/haproxy.cfg
Используйте код с осторожностью.Вставьте следующий продакшен-конфиг для балансировки MySQL/Galera:haproxyglobal
    log stdout format raw local0

defaults
    log     global
    mode    tcp            # Для баз данных используем чистый TCP
    timeout connect 5s
    timeout client  30m
    timeout server  30m

# Входная точка внутри Docker Swarm
frontend galera_in
    bind *:3306
    default_backend galera_nodes

# Распределение трафика на физические хосты Ubuntu
backend galera_nodes
    mode tcp
    option tcp-check       # Проверка доступности порта
    balance round-robin    # Равномерное распределение нагрузки

    # Прописываем ваши реальные ноды Galera Cluster
    server galera1 10.10.1.36:3306 check inter 2s rise 2 fall 3
    server galera2 10.10.1.37:3306 check inter 2s rise 2 fall 3
    server galera3 10.10.1.38:3306 check inter 2s rise 2 fall 3
Используйте код с осторожностью.Шаг 3. Запуск обновленияПримените измененную конфигурацию стека:bashsudo docker stack deploy -c prod-stack.yml hub
Используйте код с осторожностью.Как это будет работать теперь:Docker Swarm поднимет контейнеры onlyoffice-db-balancer.OnlyOffice при старте увидит корректный одиночный адрес DB_HOST=onlyoffice-db-balancer, встроенный nc успешно пройдет проверку за долю секунды.Весь трафик к базе данных пойдет через HAProxy, который будет балансировать запросы по кругу на .36, .37 и .38 хосты операционной системы. При падении любой ноды базы HAProxy за 4 секунды (fall 3) исключит её из пула.Запускайте деплой. Давайте проверим логи docker service logs hub_onlyoffice --tail 50 — проскочит ли контейнер этап проверки базы данных?hub_onlyoffice.0.xcov6n551jiy@onlyoffice-stack-3    | Waiting for connection to the onlyoffice-db-balancer host on port 3306
hub_onlyoffice.0.sxx5feu6lj69@onlyoffice-stack-2    | nc: getaddrinfo for host "onlyoffice-db-balancer" port 3306: Name or service not known
hub_onlyoffice.0.sxx5feu6lj69@onlyoffice-stack-2    | Waiting for connection to the onlyoffice-db-balancer host on port 3306
hub_onlyoffice.0.o5fmg14mhwww@onlyoffice-stack-1    | nc: getaddrinfo for host "onlyoffice-db-balancer" port 3306: Name or service not known
hub_onlyoffice.0.o5fmg14mhwww@onlyoffice-stack-1    | Waiting for connection to the onlyoffice-db-balancer host on port 3306
hub_onlyoffice.0.xcov6n551jiy@onlyoffice-stack-3    | nc: getaddrinfo for host "onlyoffice-db-balancer" port 3306: Name or service not known
hub_onlyoffice.0.xcov6n551jiy@onlyoffice-stack-3    | Waiting for connection to the onlyoffice-db-balancer host on port 3306Ошибка nc: getaddrinfo ... Name or service not known означает, что контейнеры OnlyOffice вообще не могут разрешить имя onlyoffice-db-balancer через внутренний DNS Docker.В Docker Swarm есть особенность: внутренний DNS-резолвер не создаст запись для сервиса, пока хотя бы один контейнер этого сервиса-балансировщика (haproxy) физически не перейдет в статус Running [1]. Если HAProxy долго запускается или падает, для OnlyOffice этого имени просто не существует в сети.Давайте найдем причину блокировки HAProxy.Шаг 1. Проверяем состояние балансировщикаВыполните команду на менеджер-ноде, чтобы увидеть текущий статус HAProxy:bashsudo docker stack ps hub | grep balancer
Используйте код с осторожностью.Сценарий А: Если вы видите статус Rejected или Failed с ошибкой вроде «invalid volume» или «permission denied», значит HAProxy не может прочитать файл конфигурации из GlusterFS.Сценарий Б: Если он висит в Preparing или Starting, Docker еще скачивает образ haproxy:2.8-alpine на ноды stack-2 и stack-3.Шаг 2. Самая частая причина (Ошибка чтения haproxy.cfg)Контейнер HAProxy в образе Alpine по умолчанию работает под встроенным пользователем haproxy (UID 99). Если папка /mnt/gluster-storage/haproxy, которую мы создали, принадлежит пользователю root, контейнер не может заглянуть внутрь и прочитать файл конфигурации.Давайте исправим права доступа на GlusterFS (выполните на любой одной ноде хоста):bashsudo chmod -R 755 /mnt/gluster-storage/haproxy
sudo chown -R 99:99 /mnt/gluster-storage/haproxy
Используйте код с осторожностью.Шаг 3. Использование DNS-имени с префиксом стекаЕсли команда из Шага 1 показывает, что HAProxy запущен и работает (Running), то OnlyOffice не видит его из-за того, что имя сервиса внутри overlay-сети должно включать имя стека.Поскольку наш стек называется hub, попробуйте изменить переменную в prod-stack.yml внутри секции onlyoffice на полное имя:yaml      - DB_HOST=hub_onlyoffice-db-balancer
Используйте код с осторожностью.После изменения примените стек: sudo docker stack deploy -c prod-stack.yml hub.Выполните команду sudo docker stack ps hub | grep balancer, чтобы увидеть точный статус прокси-сервиса. Что именно мешает HAProxy запуститься?| [ALERT]    (1) : config : Error(s) found in configuration file : /usr/local/etc/haproxy/haproxy.cfg
hub_onlyoffice-db-balancer.1.ovxjb3egevlo@onlyoffice-stack-1    | [ALERT]    (1) : config : Fatal errors found in configuration.
hub_onlyoffice-db-balancer.2.vivbaqvokrto@onlyoffice-stack-1    | [NOTICE]   (1) : haproxy version is 2.8.24-eea79933В HAProxy версии 2.8+ директива option tcp-check устарела и была удалена из синтаксиса. Современная версия считает её критической ошибкой, из-за чего контейнер onlyoffice-db-balancer падает на этапе парсинга конфигурации.В режиме mode tcp для проверки баз данных достаточно оставить ключевое слово check в строке каждого сервера. Балансировщик будет самостоятельно пинговать порт 3306.Давайте исправим конфигурационный файл и вернем чистоту в логи.Шаг 1. Исправление файла haproxy.cfgОткройте конфигурационный файл на хосте:bashsudo nano /mnt/gluster-storage/haproxy/haproxy.cfg
Используйте код с осторожностью.Замените весь блок backend galera_nodes на этот исправленный вариант (строка option tcp-check удалена, а метод балансировки заменен на leastconn — это более эффективная практика для СУБД, направляющая запрос на менее загруженную ноду базы):haproxy# Распределение трафика на физические хосты Ubuntu
backend galera_nodes
    mode tcp
    balance leastconn      # Направляем новые сессии на наименее загруженную ноду
   
    # Прописываем ваши реальные ноды Galera Cluster
    server galera1 10.10.1.36:3306 check inter 2s rise 2 fall 3
    server galera2 10.10.1.37:3306 check inter 2s rise 2 fall 3
    server galera3 10.10.1.38:3306 check inter 2s rise 2 fall 3
Используйте код с осторожностью.Шаг 2. Принудительный перезапуск балансировщикаПоскольку HAProxy упал, Docker Swarm пытается перезапустить его. Поможем ему применить новый файл конфигурации мгновенно:bashsudo docker service update --force hub_onlyoffice-db-balancer
Используйте код с осторожностью.Шаг 3. Финальная проверка цепочкиУбедитесь, что балансировщик перешел в статус Running:bashsudo docker stack ps hub | grep balancer
Используйте код с осторожностью.Посмотрите свежие логи onlyoffice. Ошибка разрешения имени или таймаута netcat должна исчезнуть, уступив место строкам инициализации приложения:bashsudo docker service logs hub_onlyoffice --tail 50
Используйте код с осторожностью.Как только балансировщик поднимется, DNS-имя заработает. Проверяем логи OnlyOffice
  •  

🡱 🡳

Отметьте интересные вам фрагменты текста и они станут доступны по уникальной ссылке в адресной строке браузера.