MAATRIX / Блог / Как установить и настроить Uptime Kuma на VPS

Как установить и настроить Uptime Kuma на VPS

Как установить и настроить Uptime Kuma на VPS

MAATRIX

Установка 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 — десятки моделей в одном окне. Оплата картой РФ и по СБП.