VPSРейтинг
Self-hosted2 сентября 2026 · 16 мин

Komodo на VPS: деплой из Git на несколько серверов

Когда серверов с Docker становится два и больше, обновление превращается в последовательность одинаковых действий: зайти по SSH, обновить репозиторий, поднять стек, проверить логи. Komodo делает это за вас из одной панели — и делает это по команде из вашего Git-репозитория.

Задача: три сервера и одинаковая рутина

Пока сервер один, схема простая: на нём лежит папка с compose.yaml, вы заходите по SSH, делаете git pull и docker compose up -d. Всё понятно и занимает минуту.

Проблемы начинаются, когда серверов становится несколько. Одно и то же приложение крутится на двух машинах, база — на третьей, а раскатывать изменения нужно вручную и по очереди. Появляются вопросы, на которые нет быстрого ответа: какая версия сейчас на каком сервере, кто последний раз выкатывал, почему на одном сервере работает, а на другом нет. Через полгода на серверах оказываются немного разные файлы, и никто не помнит почему.

Классический ответ — настроить CI: GitHub Actions или GitLab CI, которые по SSH ходят на серверы и выполняют команды. Работает, но требует хранить где-то приватные ключи от всех серверов, писать и поддерживать сценарий сборки, а результат виден только в логе задачи, а не в виде состояния «где что запущено».

Идея Komodo в одном предложении

На отдельный небольшой сервер ставится панель, на все остальные — маленький агент; панель хранит список стеков, привязанных к вашим Git-репозиториям, и по кнопке или по вебхуку выполняет на нужном сервере обычный docker compose up — показывая каждый шаг и его вывод.

Komodo — открытый проект под лицензией GPL-3.0, развивается с 2022 года. К сентябрю 2026 у репозитория около 12 100 звёзд, актуальная версия — 2.3.3 от 1 сентября 2026. Все команды, конфиги и сообщения об ошибках ниже проверены на реально развёрнутой установке этой версии: с Nginx, с подключением второго сервера, с деплоем стека из репозитория и с вебхуком.

Komodo, Portainer или Dockge

Панелей для Docker много, и легко взять не ту. Три самых частых варианта и разница между ними:

ПанельДля чего онаКогда брать
DockgeРедактор compose-файлов в браузере. С версии 1.4 умеет несколько серверов через агентов.Домашний сервер, файлы правятся руками, репозитория нет.
PortainerУниверсальная панель для Docker, Swarm и Kubernetes. Часть возможностей — в платной Business Edition, бесплатной до трёх узлов.Нужен подробный обзор и ручное управление, в планах Kubernetes.
KomodoПанель деплоя: стек привязан к репозиторию и ветке, есть вебхуки, сборка образов и многошаговые процедуры.Свой код в Git, несколько серверов, нужен путь «репозиторий → прод» без отдельного CI.

Дальше в статье — только Komodo. Если ваш случай описан в первых двух строках таблицы, эта установка будет лишней работой.

И ещё одна развилка, о которой стоит подумать до установки: любая такая панель — это ещё один сервис, который вы обновляете, бэкапите и чините сами. Если задача сводится к «сделал push — приложение обновилось», а несколько серверов нужны не принципиально, тот же результат дают платформы, где панель не ваша забота; из русскоязычных так работает Hostim. Плата за это — меньше контроля: вы разворачиваете приложение по правилам платформы, а не произвольный compose.yaml на своём сервере.

Как это устроено

В Komodo две программы, и это стоит понять до установки — тогда все дальнейшие шаги становятся очевидными.

Core — сама панель: веб-интерфейс, база с настройками и журналом действий. Сама она на серверах ничего не выполняет — только отдаёт команды агентам.

Periphery — агент. Его ставят на каждый сервер, которым вы хотите управлять, включая тот, где стоит панель. Агент умеет ровно то, что вы сделали бы руками: клонировать репозиторий, выполнить docker compose, отдать логи контейнера, сообщить загрузку процессора и диска.

Главное отличие второй версии: агент звонит сам

Раньше панель подключалась к агенту, и на каждом сервере приходилось открывать порт 8120 — наружу или через приватную сеть. С версии 2.0, вышедшей в марте 2026, всё наоборот: агент сам открывает соединение с панелью по её обычному HTTPS-адресу и держит его. На управляемых серверах не нужно открывать ни одного порта. Стороны узнают друг друга по паре ключей, которые генерируются автоматически: постоянного пароля, общего для всех серверов, здесь нет — при первом подключении используется одноразовый ключ, и дальше он не нужен.

Практическое следствие: серверы могут стоять у разных провайдеров и в разных странах, за NAT или за файрволом, который вообще не пропускает входящие соединения. Единственное требование — с сервера должен быть доступен адрес панели.

Многие статьи и обсуждения в интернете описывают ещё старую схему с портом 8120 и общим паролем-passkey. Она в Komodo осталась для совместимости, но для новой установки её выбирать не нужно.

Что понадобится

Для установки нужны:

  • Отдельный сервер под панель — Ubuntu 22.04 или 24.04, от 2 ГБ оперативной памяти и от 20 ГБ диска. Диск здесь важнее памяти: три образа занимают около 2 ГБ ещё до первого запуска.
  • Домен, направленный на этот сервер A-записью. Без домена не получить сертификат, а без HTTPS панель работать будет, но пароль пойдёт по сети открытым текстом.
  • Серверы, которыми вы будете управлять — с установленным Docker. Требований к их расположению нет.

Если сервера ещё нет

2 ГБ RAM · 20 ГБ диска

Панель с базой и агентом занимала в нашей установке около 350 МБ памяти, так что 2 ГБ берутся с запасом на сам Docker и Nginx. 20 ГБ диска — это примерно 2 ГБ под образы, место под базу и запас под клоны репозиториев, которые панель складывает у себя. Ставить панель на один из рабочих серверов не стоит: он же и упадёт вместе с ней.

В каталоге под эти требования подходит 108 тарифов, самый дешёвый — 429 ₽/мес (AdminVPS, 2 ГБ, 30 ГБ NVMe).

Открыть каталог с этими фильтрами →

Шаг 1. Панель на центральном сервере

Ставим Docker:

Docker + плагин compose
sudo apt update
curl -fsSL https://get.docker.com | sudo sh

Создаём каталог для установки:

каталог
sudo mkdir -p /opt/komodo
cd /opt/komodo

Первый файл описывает три контейнера: базу, панель и агента для этого же сервера. Пустая метка komodo.skip у базы взята из официального файла проекта: она выводит контейнер из-под кнопки «остановить все контейнеры», которой панель иначе выключила бы собственную базу.

sudo nano /opt/komodo/compose.yaml
services:
  mongo:
    image: mongo:8
    restart: unless-stopped
    command: --quiet --wiredTigerCacheSizeGB 0.25
    labels:
      komodo.skip:
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DATABASE_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DATABASE_PASSWORD}
    volumes:
      - mongo-data:/data/db
      - mongo-config:/data/configdb

  core:
    image: ghcr.io/moghtech/komodo-core:2
    init: true
    restart: unless-stopped
    depends_on:
      - mongo
    ports:
      - 127.0.0.1:9120:9120
    env_file: ./.env
    environment:
      KOMODO_DATABASE_ADDRESS: mongo:27017
    volumes:
      - keys:/config/keys
      - /opt/komodo/backups:/backups

  periphery:
    image: ghcr.io/moghtech/komodo-periphery:2
    init: true
    restart: unless-stopped
    depends_on:
      - core
    env_file: ./.env
    volumes:
      - keys:/config/keys
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - /etc/komodo:/etc/komodo

volumes:
  mongo-data:
  mongo-config:
  keys:

Префикс 127.0.0.1 в строке портов обязателен. Docker публикует порты в обход UFW: строка 9120:9120 откроет панель всему интернету, и никакое правило файрвола этому не помешает. С префиксом порт слушает только сам сервер, а снаружи к панели пускает Nginx — его настроим на следующем шаге.

Второй файл — настройки. Обратите внимание на имя: именно .env, с точкой в начале. Так его подхватывает и Docker Compose для подстановки в первый файл, и оба контейнера Komodo, — и вам не придётся каждый раз вспоминать дополнительный ключ в команде запуска.

sudo nano /opt/komodo/.env
TZ=Europe/Moscow

KOMODO_DATABASE_USERNAME=komodo
KOMODO_DATABASE_PASSWORD=ЗАМЕНИТЕ_ПАРОЛЬ_БАЗЫ

KOMODO_HOST=https://komodo.example.ru
KOMODO_LOCAL_AUTH=true
KOMODO_DISABLE_USER_REGISTRATION=true
KOMODO_INIT_ADMIN_USERNAME=admin
KOMODO_INIT_ADMIN_PASSWORD=ЗАМЕНИТЕ_ПАРОЛЬ_АДМИНА
KOMODO_JWT_SECRET=ЗАМЕНИТЕ_СЛУЧАЙНОЙ_СТРОКОЙ
KOMODO_WEBHOOK_SECRET=ЗАМЕНИТЕ_ДРУГОЙ_СЛУЧАЙНОЙ_СТРОКОЙ
KOMODO_FIRST_SERVER_NAME=main
KOMODO_PERIPHERY_PUBLIC_KEY=file:/config/keys/periphery.pub

PERIPHERY_CORE_ADDRESS=ws://core:9120
PERIPHERY_CONNECT_AS=main
PERIPHERY_CORE_PUBLIC_KEYS=file:/config/keys/core.pub
PERIPHERY_ROOT_DIRECTORY=/etc/komodo
PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname

Что здесь нужно поменять руками:

  • KOMODO_HOST — адрес, по которому панель будет открываться. Он не влияет на то, на каком порту работает Komodo: по нему панель строит ссылки, в том числе адрес вебхука, который вы скопируете на шаге 6. Пишите сразу с https://.
  • Четыре строки со словом ЗАМЕНИТЕ — это пароли и секреты. Каждое значение придумывается своё, повторять одно и то же нельзя.
  • KOMODO_FIRST_SERVER_NAME и PERIPHERY_CONNECT_AS — имя, под которым этот сервер появится в панели. Два значения должны совпадать; можно оставить main.

Случайные строки удобно взять так — команда выполняется четыре раза, по строке на каждое значение:

генерация секрета
openssl rand -hex 24

Пароль базы задаётся один раз. MongoDB создаёт пользователя при первом старте и запоминает его в томе с данными. Если позже поменять KOMODO_DATABASE_PASSWORD в .env, панель перестанет подключаться к базе: в файле будет новый пароль, а в базе останется старый. Выберите пароль сейчас.

Запускаем:

в каталоге /opt/komodo
sudo docker compose up -d

Первый запуск занимает пару минут — образы весят около 2 ГБ. Проверить, что всё поднялось:

журнал панели
sudo docker compose logs core | tail -20

В журнале должны быть строки Komodo Core version: v2.3.3, Successfully created init admin user и Server starting on http://[::]:9120. В журнале агента (sudo docker compose logs periphery) — строка Logged in to Komodo Core core:9120 websocket as Server main. Первая попытка подключения там обычно завершается ошибкой Connection refused: агент стартует быстрее панели и повторяет попытку через пять секунд. Это нормально.

Шаг 2. Домен, Nginx и HTTPS

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

Ставим Nginx и открываем порты:

Nginx и файрвол
sudo apt install -y nginx
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
# на вопрос про SSH-соединения ответьте y

Конфигурация сайта. Замените komodo.example.ru на свой домен:

sudo nano /etc/nginx/sites-available/komodo
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name komodo.example.ru;

    location / {
        proxy_pass http://127.0.0.1:9120;

        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

Строки, без которых агенты не подключатся. Связь между панелью и агентом идёт по веб-сокету, и Nginx должен его пропустить: за это отвечают блок map в начале файла и пара заголовков Upgrade и Connection.

Отдельно — строка proxy_set_header Host $http_host;. Именно $http_host, а не привычный $host: Komodo подмешивает заголовок Host в проверку подлинности соединения, а $host отбрасывает номер порта. На стандартном 443-м порту разницы нет, но стоит вынести панель на любой другой порт — и агенты начнут падать с ошибкой Failed to read handshake_m2: decrypt error, по которой догадаться о причине невозможно. Мы это поймали на проверочной установке.

Включаем сайт и получаем сертификат:

включение и сертификат
sudo ln -s /etc/nginx/sites-available/komodo /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d komodo.example.ru

Certbot сам допишет в конфигурацию порт 443, пути к сертификату и перенаправление с HTTP на HTTPS. Блок map и заголовки он не трогает. Получение сертификата занимает минуту-две.

Шаг 3. Первый вход

Откройте https://komodo.example.ru и войдите под именем admin с паролем из KOMODO_INIT_ADMIN_PASSWORD. Интерфейс только на английском, русского нет.

На главной странице в разделе Servers уже будет один сервер с именем main и состоянием Ok — тот самый, на котором стоит панель. Откройте его: там видны загрузка процессора, память, диск и полный список контейнеров сервера, включая те, что запускали не через Komodo.

Пользователь создан и сохранён в базе, поэтому две строки с логином и паролем администратора из .env можно убрать — панели они больше не нужны:

после первого входа
sudo sed -i '/^KOMODO_INIT_ADMIN/d' /opt/komodo/.env
cd /opt/komodo && sudo docker compose up -d core

Заодно стоит включить второй фактор: меню пользователя в правом верхнем углу → Profile → раздел 2FA. Komodo поддерживает и одноразовые коды, и ключи доступа. Дальше станет понятно, почему доступ к этой панели стоит защищать всерьёз.

Шаг 4. Подключаем второй сервер

Подключение состоит из двух действий: в панели выпускается одноразовый ключ, на сервере запускается агент с этим ключом. Больше ничего — ни портов, ни правил файрвола.

В панели. Откройте Settings → вкладка Onboarding → кнопка New Onboarding Key. Имя и срок действия можно оставить как есть, нажмите Create. Панель покажет ключ и честно предупредит: «Copy the onboarding key below. It won't be shown again» — второй раз его не показать, скопируйте сразу.

На втором сервере. Ставим Docker и создаём файл агента:

на подключаемом сервере
sudo apt update
curl -fsSL https://get.docker.com | sudo sh
sudo mkdir -p /opt/komodo
cd /opt/komodo
sudo nano /opt/komodo/compose.yaml
services:
  periphery:
    image: ghcr.io/moghtech/komodo-periphery:2
    init: true
    restart: unless-stopped
    environment:
      PERIPHERY_CORE_ADDRESS: https://komodo.example.ru
      PERIPHERY_CONNECT_AS: berlin
      PERIPHERY_ONBOARDING_KEY: ЗАМЕНИТЕ_КЛЮЧОМ_ИЗ_ПАНЕЛИ
      PERIPHERY_CORE_PUBLIC_KEYS: file:/config/keys/core.pub
      PERIPHERY_ROOT_DIRECTORY: /etc/komodo
      PERIPHERY_INCLUDE_DISK_MOUNTS: /etc/hostname
    volumes:
      - keys:/config/keys
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - /etc/komodo:/etc/komodo

volumes:
  keys:

Три значения под замену: адрес вашей панели, имя сервера в PERIPHERY_CONNECT_AS (под ним он появится в списке — здесь для примера berlin) и ключ из панели. Запускаем:

в каталоге /opt/komodo на втором сервере
sudo docker compose up -d
sudo docker compose logs -f periphery

В журнале должны появиться строки Server onboarding flow for 'berlin' successful и Logged in to Komodo Core ... websocket as Server berlin. В панели сервер berlin появится сам, создавать его руками не нужно. Строку с ключом после этого можно удалить из файла: она нужна только для первого знакомства, дальше стороны узнают друг друга по ключам, которые уже сохранены в томе keys.

Пути /etc/komodo внутри и снаружи контейнера должны совпадать. В этот каталог агент клонирует репозитории и складывает файлы стеков, а команды docker compose выполняет через сокет основного Docker — то есть пути в них трактуются как пути хоста. Если смонтировать каталог по другому пути, Docker будет искать файлы не там, где они лежат.

Остальные серверы подключаются так же — тот же файл с другим значением PERIPHERY_CONNECT_AS. Ключ при этом можно взять тот же: он не расходуется и подключает сколько угодно серверов, панель только запоминает, кто им воспользовался. Если вы его не сохранили, выпустите новый — старый на уже подключённые серверы не влияет. Когда все серверы на месте, ключ стоит удалить в том же разделе Onboarding.

Шаг 5. Стек из Git-репозитория

Стек в Komodo — это один compose-проект на одном сервере. Файлы для него можно писать прямо в панели, брать с диска сервера или из репозитория. Разбираем третий вариант: он и есть то, ради чего Komodo ставят.

Заготовка: репозиторий на GitHub, в корне которого лежит compose.yaml — обычный, без каких-либо особенностей. Например такой:

compose.yaml в вашем репозитории
services:
  web:
    image: traefik/whoami
    restart: unless-stopped
    ports:
      - "127.0.0.1:8123:80"

В панели откройте StacksNew Stack, задайте имя (например whoami) и заполните:

  • Server — на каком сервере разворачивать, например berlin.
  • Choose ModeGit Repo.
  • Source — провайдер github.com и репозиторий в виде владелец/название. Ветка уже заполнена значением main; если у вас master или любая другая, поменяйте её здесь — вебхук на шаге 6 сравнивает ветку и молча пропускает пуши в чужие.
  • FilesRun Directory оставьте пустым, если compose.yaml лежит в корне репозитория; если он в подкаталоге, укажите путь к нему.

Сохраните изменения и нажмите Deploy. Панель покажет пять шагов, и это стоит один раз прочитать целиком — видно, что никакой магии нет:

ШагЧто выполняется на сервере
Clone Repogit clone … /etc/komodo/stacks/whoami -b main
Latest Commitgit rev-parse --short HEAD && git log -1 --pretty=%B
Compose Configdocker compose -p whoami -f compose.yaml config
Compose Pulldocker compose -p whoami -f compose.yaml pull
Compose Updocker compose -p whoami -f compose.yaml up -d

То же самое вы сделали бы руками — только теперь вывод каждого шага сохранён в журнале панели вместе с хешем коммита, из которого стек собран. Имя проекта совпадает с именем стека, поэтому docker ps на сервере покажет контейнер whoami-web-1, а curl 127.0.0.1:8123 на нём же ответит страницей сервиса.

Если репозиторий приватный, нужен токен доступа: Settings ProvidersGit Accounts, там задаются домен, имя пользователя и токен. После этого учётная запись выбирается в настройках стека.

Шаг 6. Автодеплой по вебхуку

Вебхук — это адрес, на который GitHub стучится после каждого push. Komodo принимает такой запрос, проверяет подпись и, если изменения касались нужной ветки, повторяет деплой стека.

В настройках стека найдите раздел Webhooks — он свёрнут, разверните его. Оттуда нужно скопировать адрес из строки Webhook URL - Deploy. Переключатель Webhook Enabled там же включён по умолчанию, трогать его не надо — но если вебхук потом не сработает, проверьте в первую очередь его.

Адрес выглядит так — домен в нём берётся из KOMODO_HOST, так что если в .env остался пример из статьи, здесь будет он же:

адрес вебхука
https://komodo.example.ru/listener/github/stack/whoami/deploy

Дальше в репозитории на GitHub: SettingsWebhooks Add webhook. Заполните четыре поля:

  • Payload URL — скопированный адрес;
  • Content typeapplication/json;
  • Secret — значение KOMODO_WEBHOOK_SECRET из вашего .env;
  • Which eventsJust the push event.

Проверка: измените что-нибудь в compose.yaml, сделайте push — и в разделе Updates в панели появится новая запись DeployStack. На нашей проверочной установке между push и обновлённым контейнером проходило несколько секунд.

По умолчанию Komodo не разворачивает стек заново, если файлы в репозитории не менялись, — push с правкой в другой папке ничего не сломает. Чтобы понять, есть ли изменения, панель клонирует репозиторий и у себя тоже. Для публичного репозитория на GitHub это незаметно, а вот если вы держите свой Gitea в закрытой сети, доступ к нему нужен и серверу с панелью, а не только серверу со стеком.

Шаг 7. Уведомления

Komodo умеет сообщать, что сервер перестал отвечать, что кончается место на диске, что контейнер сменил состояние или что деплой не прошёл. Уведомления настраиваются в SettingsAlertersNew Alerter.

Доступны пять способов доставки: Slack, Discord, Ntfy, Pushover и Custom — отправка сообщения в формате JSON на произвольный адрес. Телеграма в списке нет, и это стоит знать заранее: чтобы сообщения приходили туда, придётся написать собственный маленький сервис-переходник и указать его адрес в типе Custom.

Самый короткий рабочий путь без своего кода — Ntfy: это push-сообщения на телефон через приложение (есть в Google Play, App Store и F-Droid). Публичный сервер ntfy.sh не требует регистрации: вы придумываете имя канала, подписываетесь на него в приложении и указываете адрес канала в панели.

тип Ntfy, поле url
https://ntfy.sh/komodo-7f3a91c4d2e8

Имя канала — это и есть весь пароль: кто его знает, тот читает ваши уведомления. Берите длинное и случайное, а не komodo-alerts. После сохранения нажмите Test Alerter — на телефон придёт сообщение с заголовком Komodo Alert. Если уведомления о серверах не должны уходить наружу вообще, ntfy ставится и на свой сервер — тогда в поле указывается его адрес.

Безопасность: что на самом деле может Komodo

Об этом лучше подумать сразу, а не после установки. Агент получает сокет Docker (/var/run/docker.sock), а с ним — возможность запустить на сервере любой контейнер с любыми правами. Плюс в панели по умолчанию включён удалённый терминал. Практический смысл простой: кто получил администратора в панели, тот получил полный доступ ко всем подключённым серверам сразу. Отсюда четыре правила.

  • Панель — только по HTTPS и только под своим доменом. Порт 9120 не публикуется наружу — это та самая строка 127.0.0.1 из первого файла.
  • Регистрация закрыта. Строка KOMODO_DISABLE_USER_REGISTRATION=true уже стоит в .env. Без неё на странице входа есть кнопка «Sign Up», и посторонний может создать себе учётную запись. Данных он не увидит — новые пользователи заводятся выключенными и до подтверждения администратором получают отказ, — но и накапливать чужие учётные записи на своей панели незачем.
  • Порт агента наружу не открывать. В исходящем режиме, который мы настроили, агент вообще ничего не слушает — проверьте, что в правилах файрвола подключённых серверов нет разрешения на 8120. Запись 8120/tcp в выводе docker ps пугать не должна: это объявление порта в образе, а не открытый порт — в файле агента нет секции ports, значит наружу ничего не отдано.
  • Терминалы выключить, если они не нужны. Две переменные в файле агента запрещают и удалённую консоль сервера, и вход внутрь контейнеров.
в блоке environment агента
PERIPHERY_DISABLE_TERMINALS: true
PERIPHERY_DISABLE_CONTAINER_TERMINALS: true

Отдельно стоит помнить про журнал: Komodo сохраняет, кто и когда что запускал, и это видно в разделе Updates — и общем, и на странице каждого стека. Если панелью пользуется не только автор установки, второй фактор при входе перестаёт быть формальностью.

Обновление и резервные копии

В файлах указан тег 2 — это последняя версия второй ветки. Обновление сводится к двум командам на сервере с панелью:

в каталоге /opt/komodo
sudo docker compose pull
sudo docker compose up -d

Те же две команды нужно выполнить на каждом подключённом сервере: версии панели и агентов должны совпадать. Если забыть, Komodo сам об этом напомнит — у него есть отдельный вид уведомления о расхождении версий.

Резервные копии базы Komodo делает сам. Сразу после установки в разделе Procedures появляется задание Backup Core Database, которое каждую ночь в час выгружает содержимое базы в каталог /opt/komodo/backups (тот, что смонтирован в первом файле) и хранит последние четырнадцать копий. Внутри — папка с датой и временем, в ней сжатые файлы коллекций. Задание можно запустить руками кнопкой Run Procedure — панель попросит подтвердить действие, введя имя задания, — и убедиться, что папка появилась. Этот каталог имеет смысл добавить в свой обычный бэкап сервера.

Частые проблемы

Агент не подключается: Failed to read handshake_m2: decrypt error

Соединение до панели доходит, но проверка подлинности не проходит. Причина почти всегда в Nginx. Проверьте три вещи в конфигурации: блок map присутствует, заголовки Upgrade и Connection проставлены, а Host передаётся как $http_host, а не $host. Вторая причина возникает, когда перед Nginx стоит ещё один прокси и подставляет свой заголовок X-Forwarded-Host: Komodo доверяет ему больше, чем Host, и при несовпадении даёт ровно эту же ошибку — мы проверили. Если такой прокси есть, убедитесь, что он передаёт исходное имя домена.

Контейнер mongo падает сразу после запуска

Посмотрите его журнал: sudo docker compose logs mongo. Если там Illegal instruction или предупреждение о поддержке AVX — процессор вашей виртуальной машины не поддерживает набор инструкций, который требуется MongoDB начиная с пятой версии. Это встречается на старом железе и на некоторых гипервизорах. Решение есть у самого проекта: вместо MongoDB используется FerretDB поверх PostgreSQL, готовый файл лежит в репозитории Komodo под именем ferretdb.compose.yaml, остальные шаги статьи не меняются.

Деплой падает на шаге Compose Up: address already in use

Порт из вашего compose.yaml занят другим контейнером или службой на этом сервере. Komodo здесь ни при чём — это обычная ошибка Docker, и точно так же она возникла бы при запуске руками. Посмотрите занятые порты командой sudo ss -ltnp и поменяйте порт в репозитории. Обратите внимание: часть контейнеров при этом остаётся запущенной — они успевают стартовать до того, как сбойный сервис уронит команду.

Вебхук приходит, но ничего не происходит

Три причины по частоте. Первая: ветка в настройках стека не совпадает с той, в которую был push. В поле Branch по умолчанию стоит main, а репозиторий может жить на master — Komodo сравнивает значения и молча пропускает пуши в чужие ветки. Вторая: панель не увидела изменений в файлах стека, и это правильное поведение — стек разворачивается заново, только когда содержимое действительно поменялось. Третья: поле Branch кто-то очистил — тогда панель прямо пишет об этом в разделе Webhooks. На стороне GitHub полезно открыть Recent Deliveries у вебхука: там видно, какой ответ вернула панель.

Коротко: порядок действий

  1. Отдельный сервер под панель, домен направлен на него A-записью.
  2. Docker, каталог /opt/komodo, два файла: compose.yaml и .env.
  3. Четыре секрета в .env заменены, порт панели привязан к 127.0.0.1.
  4. sudo docker compose up -d, проверка журнала панели и агента.
  5. Nginx с блоком map, заголовками Upgrade и Host $http_host, затем certbot.
  6. Вход в панель, второй фактор, удаление строк с паролем администратора из .env.
  7. Ключ в Settings → Onboarding, агент на втором сервере, сервер появляется сам.
  8. Стек в режиме Git Repo, деплой, затем вебхук в настройках репозитория.
  9. Уведомления в Settings → Alerters и проверка кнопкой Test Alerter.

Частые вопросы

Под панель нужна отдельная машина — та, которая не упадёт вместе с рабочими серверами. Требования к ней те же, что в разделе выше: 2 ГБ памяти и 20 ГБ диска, виртуализация не OpenVZ.

Провайдеры для Docker-стека