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:
sudo apt update
curl -fsSL https://get.docker.com | sudo shСоздаём каталог для установки:
sudo mkdir -p /opt/komodo
cd /opt/komodoПервый файл описывает три контейнера: базу, панель и агента для этого же сервера. Пустая метка komodo.skip у базы взята из официального файла проекта: она выводит контейнер из-под кнопки «остановить все контейнеры», которой панель иначе выключила бы собственную базу.
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, — и вам не придётся каждый раз вспоминать дополнительный ключ в команде запуска.
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, панель перестанет подключаться к базе: в файле будет новый пароль, а в базе останется старый. Выберите пароль сейчас.
Запускаем:
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 и открываем порты:
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 на свой домен:
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.ruCertbot сам допишет в конфигурацию порт 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/komodoservices:
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) и ключ из панели. Запускаем:
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 — обычный, без каких-либо особенностей. Например такой:
services:
web:
image: traefik/whoami
restart: unless-stopped
ports:
- "127.0.0.1:8123:80"В панели откройте Stacks → New Stack, задайте имя (например whoami) и заполните:
- Server — на каком сервере разворачивать, например
berlin. - Choose Mode —
Git Repo. - Source — провайдер
github.comи репозиторий в видевладелец/название. Ветка уже заполнена значениемmain; если у васmasterили любая другая, поменяйте её здесь — вебхук на шаге 6 сравнивает ветку и молча пропускает пуши в чужие. - Files —
Run Directoryоставьте пустым, еслиcompose.yamlлежит в корне репозитория; если он в подкаталоге, укажите путь к нему.
Сохраните изменения и нажмите Deploy. Панель покажет пять шагов, и это стоит один раз прочитать целиком — видно, что никакой магии нет:
| Шаг | Что выполняется на сервере |
|---|---|
| Clone Repo | git clone … /etc/komodo/stacks/whoami -b main |
| Latest Commit | git rev-parse --short HEAD && git log -1 --pretty=%B |
| Compose Config | docker compose -p whoami -f compose.yaml config |
| Compose Pull | docker compose -p whoami -f compose.yaml pull |
| Compose Up | docker compose -p whoami -f compose.yaml up -d |
То же самое вы сделали бы руками — только теперь вывод каждого шага сохранён в журнале панели вместе с хешем коммита, из которого стек собран. Имя проекта совпадает с именем стека, поэтому docker ps на сервере покажет контейнер whoami-web-1, а curl 127.0.0.1:8123 на нём же ответит страницей сервиса.
Если репозиторий приватный, нужен токен доступа: Settings → Providers → Git Accounts, там задаются домен, имя пользователя и токен. После этого учётная запись выбирается в настройках стека.
Шаг 6. Автодеплой по вебхуку
Вебхук — это адрес, на который GitHub стучится после каждого push. Komodo принимает такой запрос, проверяет подпись и, если изменения касались нужной ветки, повторяет деплой стека.
В настройках стека найдите раздел Webhooks — он свёрнут, разверните его. Оттуда нужно скопировать адрес из строки Webhook URL - Deploy. Переключатель Webhook Enabled там же включён по умолчанию, трогать его не надо — но если вебхук потом не сработает, проверьте в первую очередь его.
Адрес выглядит так — домен в нём берётся из KOMODO_HOST, так что если в .env остался пример из статьи, здесь будет он же:
https://komodo.example.ru/listener/github/stack/whoami/deployДальше в репозитории на GitHub: Settings → Webhooks → Add webhook. Заполните четыре поля:
- Payload URL — скопированный адрес;
- Content type —
application/json; - Secret — значение
KOMODO_WEBHOOK_SECRETиз вашего.env; - Which events — Just the push event.
Проверка: измените что-нибудь в compose.yaml, сделайте push — и в разделе Updates в панели появится новая запись DeployStack. На нашей проверочной установке между push и обновлённым контейнером проходило несколько секунд.
По умолчанию Komodo не разворачивает стек заново, если файлы в репозитории не менялись, — push с правкой в другой папке ничего не сломает. Чтобы понять, есть ли изменения, панель клонирует репозиторий и у себя тоже. Для публичного репозитория на GitHub это незаметно, а вот если вы держите свой Gitea в закрытой сети, доступ к нему нужен и серверу с панелью, а не только серверу со стеком.
Шаг 7. Уведомления
Komodo умеет сообщать, что сервер перестал отвечать, что кончается место на диске, что контейнер сменил состояние или что деплой не прошёл. Уведомления настраиваются в Settings → Alerters → New Alerter.
Доступны пять способов доставки: Slack, Discord, Ntfy, Pushover и Custom — отправка сообщения в формате JSON на произвольный адрес. Телеграма в списке нет, и это стоит знать заранее: чтобы сообщения приходили туда, придётся написать собственный маленький сервис-переходник и указать его адрес в типе Custom.
Самый короткий рабочий путь без своего кода — Ntfy: это push-сообщения на телефон через приложение (есть в Google Play, App Store и F-Droid). Публичный сервер ntfy.sh не требует регистрации: вы придумываете имя канала, подписываетесь на него в приложении и указываете адрес канала в панели.
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, значит наружу ничего не отдано. - Терминалы выключить, если они не нужны. Две переменные в файле агента запрещают и удалённую консоль сервера, и вход внутрь контейнеров.
PERIPHERY_DISABLE_TERMINALS: true
PERIPHERY_DISABLE_CONTAINER_TERMINALS: trueОтдельно стоит помнить про журнал: Komodo сохраняет, кто и когда что запускал, и это видно в разделе Updates — и общем, и на странице каждого стека. Если панелью пользуется не только автор установки, второй фактор при входе перестаёт быть формальностью.
Обновление и резервные копии
В файлах указан тег 2 — это последняя версия второй ветки. Обновление сводится к двум командам на сервере с панелью:
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 у вебхука: там видно, какой ответ вернула панель.
Коротко: порядок действий
- Отдельный сервер под панель, домен направлен на него A-записью.
- Docker, каталог
/opt/komodo, два файла:compose.yamlи.env. - Четыре секрета в
.envзаменены, порт панели привязан к127.0.0.1. sudo docker compose up -d, проверка журнала панели и агента.- Nginx с блоком
map, заголовкамиUpgradeиHost $http_host, затем certbot. - Вход в панель, второй фактор, удаление строк с паролем администратора из
.env. - Ключ в Settings → Onboarding, агент на втором сервере, сервер появляется сам.
- Стек в режиме Git Repo, деплой, затем вебхук в настройках репозитория.
- Уведомления в Settings → Alerters и проверка кнопкой Test Alerter.
Частые вопросы
Под панель нужна отдельная машина — та, которая не упадёт вместе с рабочими серверами. Требования к ней те же, что в разделе выше: 2 ГБ памяти и 20 ГБ диска, виртуализация не OpenVZ.
Провайдеры для Docker-стека→