Как установить и настроить Uptime Kuma на VPS
Установка Uptime Kuma — это одна команда docker compose up -d, и через минуту у вас работает мониторинг доступности. Вопросы начинаются сразу после: панель открыта всему интернету на голом HTTP, ufw deny 3001 почему-то не помогает, а без Docker непонятно, с какой стороны подступиться. Разберём оба способа установки до рабочего состояния — с доменом, HTTPS, первыми мониторами и бэкапом.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что именно вы ставите: версии и границы
Uptime Kuma — self-hosted мониторинг доступности: раз в N секунд он стучится к вашим сайтам, API и портам снаружи и шумит, когда ответ не такой, как ожидался. Это не система метрик — какой процесс съел CPU, покажет Netdata. Зато Kuma скажет, что фронт отдаёт 502 и что сертификат протухнет через шесть дней.
Про версии. Стабильная ветка — 1.23.x, тег образа louislam/uptime-kuma:1. Ветка 2 (:2) переводит хранилище на новую схему и умеет внешнюю базу вместо SQLite, но переезд односторонний: после первого запуска :2 база мигрирует, и контейнер :1 на этих данных уже не поднимется. Тег latest не используйте вовсе — однажды он приедет мажорным обновлением сам.
И правило, которое ломает половину внедрений: Uptime Kuma нельзя ставить на тот сервер, за которым он следит. Упадёт машина — мониторинг умрёт вместе с сайтом и уведомить не успеет. Нужен отдельный VPS, желательно в другой сети и другой стране. Поэтому под него берут маленький дешёвый сервер отдельно от продакшена.
Подготовка сервера и ловушка с портом 3001
Ставим на чистую Ubuntu 24.04 LTS или Debian 12:
apt update && apt upgrade -y && apt install -y ca-certificates curl
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker compose version
Последняя команда должна ответить строкой вида Docker Compose version v2.3x.x. Отвечает docker: 'compose' is not a docker command — у вас старый docker-compose через дефис, доставьте плагин docker-compose-plugin. Каталог под данные делаем bind-mount'ом (mkdir -p /opt/uptime-kuma/data), а не именованным томом: его видно глазами и проще переносить между серверами.
Фаервол: наружу нужны только SSH и веб, порт 3001 снаружи не нужен никогда.
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw --force enable
А теперь ловушка, на которой спотыкаются почти все: ufw deny 3001/tcp порт не закроет. Публикация через -p 3001:3001 создаёт правила DNAT в таблице nat, и они отрабатывают раньше, чем цепочки ufw в filter. Панель останется открытой всему интернету, а ufw status будет бодро показывать 3001 DENY Anywhere. Проверяется с любой посторонней машины:
curl -sI http://ВАШ_IP:3001 | head -1
# HTTP/1.1 302 Found <- порт открыт, ufw ни при чём
Лечение делается на этапе установки: привязать порт к петле, а не публиковать на всех интерфейсах.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Uptime KumaУстановка через Docker Compose и первый вход
Создайте /opt/uptime-kuma/compose.yaml:
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- ./data:/app/data
environment:
TZ: Europe/Moscow
"127.0.0.1:3001:3001" — ответ на предыдущий раздел: снаружи порта просто не существует. restart: unless-stopped поднимает контейнер после перезагрузки; без этой строки после первого ребута мониторинг исчезает, и узнаёте вы об этом в худший момент. TZ избавляет от UTC в интерфейсе и уведомлениях. А healthcheck писать не нужно — он вшит в образ с параметром --start-period=180s, поэтому первые три минуты docker compose ps показывает health: starting. Это не поломка, а окно прогрева.
cd /opt/uptime-kuma
docker compose up -d
ss -tlnp | grep 3001
ss должен показать ровно 127.0.0.1:3001, а не 0.0.0.0:3001 — это и есть доказательство, что порт закрыт. В docker compose ps через пару минут появится Up 2 minutes (healthy).
Пока домена нет, заходим туннелем: ssh -L 3001:127.0.0.1:3001 root@ВАШ_IP, дальше http://127.0.0.1:3001 в браузере на своей машине. Kuma покажет страницу /setup и попросит завести администратора. Регистрация одноразовая: второй пользователь через веб не заводится, восстановления пароля по почте нет. Если забудете — сброс делается на остановленном контейнере:
docker compose stop
docker run --rm -it -v /opt/uptime-kuma/data:/app/data louislam/uptime-kuma:1 npm run reset-password
docker compose start
Сразу после входа включите 2FA в Profile → Security: панель знает адреса и порты всех ваших внутренних сервисов.
Установка без Docker: Node.js и systemd-юнит
Docker есть не везде — бывает политика компании, OpenVZ-контейнер или уже собранный Node-стек. Ручная установка рабочая, но требует внимания к версии Node.
Ветка 1.23.x собирается на Node.js 18 или 20. На Node 22 и новее нативные модули падают в node-gyp, так что «поставлю самый свежий» здесь не работает. Системный пакет nodejs в Ubuntu 24.04 — это 18.19, его достаточно; если хотите 20, берите NodeSource:
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs git build-essential python3
node -v # v20.x
build-essential и python3 нужны для сборки нативных модулей — без них npm упадёт с gyp ERR! find Python. Дальше отдельный пользователь, код и установка:
useradd --system --create-home --home-dir /var/lib/uptime-kuma --shell /usr/sbin/nologin kuma
git clone https://github.com/louislam/uptime-kuma.git /opt/uptime-kuma
chown -R kuma:kuma /opt/uptime-kuma /var/lib/uptime-kuma
sudo -u kuma bash -c 'cd /opt/uptime-kuma && npm run setup'
npm run setup сам переключается на последний тег ветки 1.23, ставит зависимости в production-режиме и скачивает собранный фронтенд. На 1 vCPU это 3–6 минут тишины в консоли. Юнит /etc/systemd/system/uptime-kuma.service:
[Unit]
Description=Uptime Kuma
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=kuma
Group=kuma
WorkingDirectory=/opt/uptime-kuma
Environment=NODE_ENV=production
Environment=UPTIME_KUMA_HOST=127.0.0.1
Environment=UPTIME_KUMA_PORT=3001
Environment=DATA_DIR=/var/lib/uptime-kuma/
ExecStart=/usr/bin/node /opt/uptime-kuma/server/server.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
Две детали, которые стоят потерянного вечера. DATA_DIR обязан заканчиваться слешем — путь склеивается с именем файла напрямую, и без слеша база уедет в /var/lib/uptime-kumakuma.db. И UPTIME_KUMA_HOST=127.0.0.1 — ручной аналог привязки к петле, здесь Docker уже ничего за вас не решает.
systemctl daemon-reload && systemctl enable --now uptime-kuma
journalctl -u uptime-kuma -f
В журнале должно появиться Listening on 3001. Обновление тут ручное — git fetch, новый тег, повторный npm run setup; в Docker это одна команда, и в этом главный аргумент в его пользу.
Домен, HTTPS и две настройки внутри панели
Дашборд Kuma работает на socket.io поверх WebSocket, поэтому реверс-прокси обязан пропускать апгрейд соединения. Проще всего с Caddy — он сам берёт сертификат Let's Encrypt и сам проксирует WebSocket:
status.example.com {
reverse_proxy 127.0.0.1:3001
}
На Nginx нужен явный блок. Сначала A-запись домена на IP сервера, потом apt install -y nginx certbot python3-certbot-nginx и certbot --nginx -d status.example.com. В server-блоке с TLS:
listen 443 ssl;
http2 on; # nginx 1.25.1+; на nginx 1.24 из Ubuntu 24.04 — listen 443 ssl http2;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
}
Применяем nginx -t && systemctl reload nginx. Пропустите строки апгрейда — логин откроется, а дальше будет вечный спиннер; разбор симптома лежит в частых ошибках Uptime Kuma.
Дальше два переключателя в панели, без которых часть функций врёт:
- Settings → General → Primary Base URL — впишите
https://status.example.com. Иначе ссылки в уведомлениях и адреса бейджей собираются из заголовка запроса, и в Telegram прилетит ссылка наhttp://127.0.0.1:3001. - Settings → Reverse Proxy → Trust Proxy — включите. Без него Kuma видит IP Nginx у всех клиентов, и лимитер входа считает их одной кучей: чужой перебор пароля заблокирует лично вас сообщением
Too frequently, try again later.
Первые мониторы, уведомления и бэкап
Add New Monitor — и первое решение, тип проверки. HTTP(s) для сайтов и API, HTTP(s) - Keyword для случая, когда приложение сломано, а код ответа всё ещё 200, TCP Port для баз и SMTP, Ping для сетевых узлов, Docker Container для контейнеров и Push для задач по расписанию.
Из настроек монитора при установке достаточно тронуть две. Retries по умолчанию 0, то есть первый же сетевой чих объявляется падением — ставьте 2–3. Request Timeout по умолчанию 48 секунд, для лёгкого эндпоинта это много — хватит 10–15. Тонкая настройка разобрана отдельно, в статье про мониторинг сайта и сервера.
Push-монитор стоит завести сразу — это самая недооценённая возможность Kuma. Он выдаёт URL вида https://status.example.com/api/push/hK7dQ2xV?status=up&msg=OK&ping=, и если по нему не постучались дольше заданного интервала, монитор падает. Вешаете вызов на хвост ночной задачи — и узнаёте про бэкап, который перестал делаться месяц назад:
0 4 * * * /opt/backup.sh && curl -fsS -m 10 "https://status.example.com/api/push/hK7dQ2xV?status=up&msg=ok"
Канал уведомлений в Settings → Notifications создаётся один раз, а потом привязывается галочкой к каждому монитору. При создании поставьте чекбоксы Default enabled и Apply on all existing monitors — иначе канал будет существовать и молчать.
Бэкап настраивайте в день установки, а не после первой потери. Всё состояние — один каталог, и в нём три файла kuma.db, kuma.db-shm, kuma.db-wal: это SQLite в режиме WAL. Копировать у живого контейнера один kuma.db нельзя — получите базу без последних транзакций. Останавливайте на время архивации, простой выйдет секунд десять:
cd /opt/uptime-kuma && docker compose stop
tar czf /root/kuma-$(date +%F).tar.gz -C /opt/uptime-kuma data
docker compose start
Встроенный Settings → Backup этому не замена: в 1.23 он помечен как deprecated и выгружает только список мониторов и уведомлений, без истории. И сразу загляните в Settings → Monitor History: срок хранения по умолчанию 180 дней, а один монитор с интервалом 60 секунд пишет 1440 строк в сутки. Полсотни мониторов за полгода — это гигабайты базы и тормозящие графики; 30–90 дней хватает почти всем.
Какой сервер под Uptime Kuma брать в MAATRIX
Uptime Kuma — процесс Node.js, который почти всё время ждёт ответа по сети. Процессор нужен минимальный, память — умеренно, диск — под базу истории.
Минимум: 1 vCPU, 1 ГБ RAM, 20 ГБ NVMe. Хватает на 15–25 мониторов. Замер на свежем инстансе: docker stats --no-stream показывает 150–190 МБ в покое, при полусотне мониторов — 300–400 МБ. Честное ограничение: на 1 ГБ ручная установка из четвёртого раздела упирается в память на этапе npm run setup — сборка нативных модулей на голом гигабайте вылетает по OOM. Ставите руками — добавьте подкачку заранее:
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Комфортный вариант: 2 vCPU, 2–4 ГБ RAM, 40 ГБ NVMe. Сотня-полторы мониторов с интервалом 30–60 секунд, Nginx с certbot рядом, полгода истории и место под ежедневные архивы. Больше памяти брать незачем: рост числа мониторов упирается в сеть и в однопоточный Node, поэтому на двух сотнях добавляйте ядра, а не гигабайты.
Локация — Великобритания, Лондон. Логика та же, что и в правиле «не на том же сервере»: точка наблюдения должна быть вне вашей продовой сети и вне вашей автономной системы, иначе вы мониторите себя через самого себя. Лондон удобен как нейтральная европейская площадка: RTT из Москвы 40–50 мс, до Франкфурта и Амстердама около 10 мс — проверки идут часто и без ложных таймаутов. Франция даёт ту же картину и тот же правовой контур. Если продакшен у вас как раз в Европе — разведите площадки и возьмите US. RU-локация оправдана, когда важно видеть доступность глазами российского пользователя: маршрут из Москвы и из Лондона разный, и обрыв бывает виден только с одной стороны.
Uptime Kuma есть в каталоге apps.maatrix.io — при заказе сервера он разворачивается автоматически, команды из этой статьи вставлять руками не нужно. Автоустановка работает на Ubuntu и Debian; берите Ubuntu 24.04 LTS. Доступы появятся в личном кабинете, в разделе «Доступ». Первые три действия после входа: сменить пароль администратора, включить 2FA и повесить домен с HTTPS по конфигу из пятого раздела. Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT: иностранная карта не нужна, хотя сервер стоит в Лондоне. Это тоже часть надёжности — сторож не должен выключаться из-за не прошедшего платежа.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Uptime KumaОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Можно ли установить Uptime Kuma без Docker?
Да: git clone, npm run setup под отдельным пользователем и systemd-юнит. Нужен Node.js 18 или 20 (на 22 сборка нативных модулей падает), пакеты build-essential и python3, а в юните DATA_DIR обязательно со слешем на конце. Минус один: обновляться придётся тоже руками.
Закрыл порт 3001 через ufw deny, а панель всё равно открывается снаружи. Почему?
Публикация порта Docker'ом создаёт правила DNAT, которые обходят цепочки ufw, и ufw status показывает запрет, которого фактически нет. Публикуйте порт на петлю — "127.0.0.1:3001:3001", — а наружу пускайте только через Nginx или Caddy.
Как перенести Uptime Kuma на другой сервер?
Остановите контейнер, заберите каталог data целиком (там kuma.db вместе с -wal и -shm), распакуйте на новом сервере в тот же путь и поднимите такой же compose-файл. Версия образа должна совпадать: данные, мигрированные веткой :2, обратно на :1 не поднимутся.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.