Як встановити Uptime Kuma в Docker
Налаштуйте моніторинг сайтів, DNS та портів через Uptime Kuma в Docker. Дізнайтеся, чому важливо запускати контейнер на окремому VPS для надійності сповіщень.
Що ви створюєте
Один невеликий контейнер, який перевіряє ваші сервери та вебсайти зовні. Він сповіщає про відсутність відповіді через email, Telegram, Discord або webhook. Uptime Kuma — це один процес Node.js, що використовує файл SQLite. Він споживає 256-512 MB RAM і надає панель моніторингу в реальному часі, графіки історії та публічну сторінку статусу. Встановлення виконується за допомогою Compose-файлу з десяти рядків. Найважливіше — це місце запуску та результати тестових сповіщень. Монітор, здатність якого до зв'язку не перевірена, не корисний: він створює ілюзію захисту, хоча насправді нічого не контролює.
Запускайте монітор там, де збій не зможе його заблокувати
Це ключове рішення, тому він є першим у списку. Не запускайте Uptime Kuma на тому ж сервері, який ви моніторите. Якщо монітор працює на сервері, який він перевіряє, то саме подія, яку ви хочете відстежити (відмова сервера або брак пам'яті), вимкне і сам монітор. У такому разі ви не отримаєте сповіщення: відсутність даних від неактивного монітора виглядає так само, як статус «все в порядку». Існує інша проблема, поки сервер працює: монітор, налаштований на localhost, ділить ресурси CPU з робочим навантаженням. Стрибок навантаження може призвести до тайм-ауту перевірки, через що статус зміниться на down. Це буде помилкове сповіщення, хоча реальні користувачі зможуть працювати без проблем.
Тому запускайте Uptime Kuma на іншому VPS, ніж той, який ви моніторите. В ідеалі — у іншого провайдера або в іншому регіоні, щоб доступ до ваших сервісів здійснювався так само, як у користувачів: через публічний інтернет, за hostname. Достатньо дешевого інстансу; одного невеликого VPS достатньо для моніторингу всіх ваших серверів. Щоб відстежити збій самого Kuma, налаштуйте push heartbeat через cron на іншому пристрої.
Prerequisites and sizing
- Чиста VPS на Ubuntu 24.04 з Docker Engine та плагіном Compose v2. Встановлюйте їх з офіційного репозиторію Docker, а не з пакетів
docker.io, оскільки вони застарілі. - 256 MB RAM достатньо для кількох моніторів; 512 MB — 1 GB забезпечить стабільну роботу десятків моніторів та reverse proxy. Навантаження на CPU мінімальне між циклами перевірок.
- Домен та DNS
Aзапис (наприклад,status.example.com, що вказує на VPS), тільки якщо вам потрібні TLS та публічна сторінка статусу. Для приватної інстанції можна обійтися без DNS, використовуючи VPN або SSH-тунель. - Вихідний мережевий доступ до сервісів сповіщень: SMTP для вашого поштового провайдера або HTTPS для Telegram та Discord.
Файл Compose
Помістіть цей вміст у /srv/uptime-kuma/compose.yaml.
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- kuma-data:/app/data
volumes:
kuma-data:Запустіть контейнер та спостерігайте за першим завантаженням:
sudo mkdir -p /srv/uptime-kuma
# save the file above as /srv/uptime-kuma/compose.yaml, then:
cd /srv/uptime-kuma && sudo docker compose up -d
sudo docker compose logs -f uptime-kumaПри успішному запуску у логах з'явиться Listening on 3001, після чого запис припиниться. У цьому файлі навмисно застосовано три налаштування.
127.0.0.1:3001:3001, а не 3001:3001. Docker створює правила DNAT для публікації портів до того, як пакет потрапить до ufw. Тому звичайний 3001:3001 відкриває ваш дашборд у відкритому інтернеті незалежно від налаштувань фаєрволу. Прив'язка до loopback робить сервіс приватним, залишаючи доступним лише reverse proxy; приватний екземпляр може обійти проксі та підключитися до 3001 через self-hosted WireGuard VPN.
Іменований volume за шляхом /app/data. Усі дані Uptime Kuma — база даних SQLite, ваші монітори, налаштування сповіщень та логотипи сторінок статусу — зберігаються там. Втрата цих даних призведе до порожнього екрана адміністрування; це єдиний об'єкт, який необхідно резервувати.
Образ зафіксовано на основному тегу :2. Це поточна стабільна лінія; перевірте Docker Hub на наявність новіших основних версій перед копіюванням. Не використовуйте плаваючі теги на кшталт latest, оскільки розробники відмовилися від них. Зміна основної версії цього образу викликає односторонню міграцію бази даних; це має бути свідомий крок, а не випадковий результат звичайного pull.
Важливе зауваження: /app/data має бути розміщено на файловій системі з підтримкою POSIX file locks. Локальний Docker volume підходить; на NFS база даних SQLite пошкоджується, що призводить до SQLITE_BUSY та database disk image is malformed, тому ніколи не використовуйте мережеві ресурси.
Перший запуск: створення облікового запису адміністратора
Перейдіть до екземпляра через ваш proxy за адресою https://status.example.com або через SSH-тунель: виконайте ssh -L 3001:127.0.0.1:3001 user@your-vps і відкрийте http://localhost:3001. Перша сторінка — це форма налаштування імені користувача та пароля адміністратора; стандартних облікових даних немає. Виберіть надійний пароль: цей дашборд має доступ до внутрішніх адрес і токенів усіх об'єктів моніторингу. Якщо ви забудете пароль, скиньте його на хості, а не в браузері:
sudo docker compose exec uptime-kuma npm run reset-passwordСпочатку додайте канали сповіщень, а потім протестуйте їх
Налаштуйте сповіщення перед додаванням моніторів. Це дозволить підключати канал під час створення кожного монітора. Перейдіть у Settings, потім у Notifications, потім у Setup Notification. Використовуйте кнопку Test для кожного каналу, щоб підтвердити отримання повідомлення. Непротестоване сповіщення — це друга найчастіша причина прихованого збою налаштувань.
Email (SMTP). Заповніть поля host, port, encryption, username, password, а також From та To. Працюють два варіанти: 465 з параметром "Secure" у режимі TLS/SSL або 587 з режимом STARTTLS. Для Gmail та більшості сервісів із двофакторною автентифікацією необхідно згенерувати app password; звичайний пароль від облікового запису поверне помилку Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Telegram. Напишіть повідомлення @BotFather, надішліть /newbot та скопіюйте bot token. Щоб дізнатися chat ID, надішліть повідомлення новому боту, відкрийте https://api.telegram.org/bot<token>/getUpdates та знайдіть chat.id у JSON-відповіді. Бот, якому ви раніше не писали, має порожній getUpdates, тому він не зможе надіслати повідомлення.
Discord. У потрібному каналі відкрийте Edit Channel, потім Integrations, потім Webhooks, потім New Webhook. Скопіюйте URL і вставте його як сповіщення типу Discord.
Generic webhook. Для інших сервісів (наприклад, Slack incoming webhook, кастомні endpoint або хуки для систем автоматизації будинку) використовуйте тип Webhook. Він надсилає JSON-пакет методом POST на вказаний вами URL. Вбудована інтеграція Apprise підтримує більшість із дев'яноста інших сервісів у списку.
Додайте монітори, по одному за раз
Натисніть Add New Monitor, виберіть тип і встановіть Friendly Name, Check Interval (рекомендовано 60 секунд), Retries (кількість послідовних помилок перед статусом "down"; встановіть 2 або 3, щоб один втрачений пакет не викликав сповіщення) та налаштування сповіщень. Типи, які ви будете використовувати:
- HTTP(s). Повна URL-адреса. Статус "up" означає прийнятий код відповіді (за замовчуванням 200-299; змініть діапазон у полі Accepted Status Codes, якщо для вас нормальним є
301або401). Основний інструмент для перевірки вебсайтів та API. - HTTP(s) - Keyword. Той самий запит, але статус "up" також вимагає наявності певної текстової фрази в тілі відповіді (якщо параметр Invert не активовано). Це дозволяє виявити помилку, коли сайт повертає
200 OK, але відображає текст "Error establishing a database connection", що звичайний HTTP-запит вважатиме успішним. - TCP Port. Пряме TCP-з'єднання з хостом та портом для протоколів, відмінних від HTTP: SSH на 22, Postgres на 5432, SMTP-сервер на 25 або ігровий сервер.
- Ping. ICMP echo: перевірка доступності та затримки. Проте багато мереж та хмарних брандмауерів блокують ICMP, тому червоний статус монітора ping може означати як "хост недоступний", так і "провайдер блокує ping"; перевіряйте це за допомогою TCP-монітора.
- DNS. Виконує запит до зазначеного резолвера для перевірки запису (A, AAAA, MX, TXT тощо) і може перевіряти відповідь. Це дозволяє вчасно виявити збої реєстратора або DNS-сервера.
- Push. Моніторинг за принципом "push" (зсередини назовні), про який наведено далі.
Моніторинг cron-завдання за допомогою push-моніторингу (heartbeat)
Кожен наведений вище монітор звертається до вашого сервісу ззовні. Push-монітор працює інакше: Uptime Kuma чекає, а ваше завдання надсилає запит, щоб підтвердити виконання. Це єдиний надійний спосіб моніторингу резервного копіювання або cron-завдань: HTTP-перевірка підтверджує лише доступність URL, але лише саме завдання знає, чи воно завершилося успішно.
Створіть монітор типу Push. Uptime Kuma згенерує унікальний URL:
https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=Встановіть Heartbeat Interval відповідно до частоти запуску завдання, додавши невеликий запас часу. Потім додайте один рядок у кінець скрипта, щоб запит надсилався лише у разі успішного виконання:
#!/usr/bin/env bash
set -euo pipefail
# ... your backup or job runs here; set -e aborts on any failure ...
curl -fsS --retry 3 "https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=backup+ok&ping="Якщо завдання завершиться помилкою, set -e перерве виконання до виклику curl; якщо сервер вимкнено, скрипт також не запуститься. У будь-якому разі heartbeat припиниться, і після закінчення вікна (інтервал + кількість спроб) Uptime Kuma змінить статус монітора на down і надішле сповіщення. Ставтеся до цього push-токена як до секретного даних: будь-хто, хто має цей токен, може імітувати успішне виконання.
Створення публічної сторінки статусу
Сторінка статусу — це інтерфейс для клієнтів. Вона показує стан сервісів та історію їхньої роботи, не надаючи доступу до вашої панелі керування. Перейдіть у Status Pages, потім у New Status Page. Введіть назву та slug (публічний шлях, наприклад /status/main). Перетягніть потрібні монітори у групи, як-от "Websites" або "APIs". Додайте логотип та короткий опис, після чого натисніть Save. Ви також можете прив'язати сторінку до окремого домену, щоб status.example.com обслуговував її безпосередньо.
Два застереження: додавайте лише ті монітори, інформацію про які ви готові оприлюднювати, оскільки сторінка статусу підтверджує наявність сервісу та його стан; панель керування залишається захищеною авторизацією, тоді як сторінка статусу є публічною за задумом і не потребує автентифікації.
Використовуйте reverse proxy з TLS та враховуйте websockets
Для публічного екземпляра налаштуйте reverse proxy перед контейнером, що працює на loopback, щоб забезпечити TLS та використання hostname. Основна складність: інтерфейс Uptime Kuma — це додаток Socket.IO, тому проксі має підтримувати upgrade WebSocket-з'єднання. Якщо це не налаштувати, сторінка завантажиться, але з'єднання не встановиться; на дашборді буде відображатися статус "Connecting...", дані не оновлюватимуться, а в консолі браузера з'явиться помилка WebSocket connection to 'wss://.../socket.io/...' failed.
Встановіть nginx та certbot, потім створіть vhost, який проксіює запити на loopback-порт. На початковому етапі використовуйте порт 80, а потім дозвольте certbot додати TLS; питання налаштування, таймерів оновлення та помилок їх виконання описано в issuing Let's Encrypt certificates with certbot and nginx.
sudo apt install -y nginx certbot python3-certbot-nginxЗбережіть цей файл як /etc/nginx/sites-available/status.example.com; ключовими є два рядки для WebSocket:
server {
listen 80;
server_name status.example.com;
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-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;
}
}Увімкніть сайт, перевірте конфігурацію, після чого дозвольте certbot переписати блок для прослуховування порту 443, додайте сертифікати та налаштуйте HTTP-to-HTTPS redirect:
sudo ln -s /etc/nginx/sites-available/status.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d status.example.comПара Upgrade та Connection "upgrade" є критично важливою, а proxy_read_timeout 3600s запобігає розриву тривалих з'єднань сокетів; certbot копіює обидва параметри у згенерований блок 443. Якщо ви вже використовуєте кілька контейнерів через один проксі, routing them through Traefik with automatic TLS забезпечує аналогічну поведінку за допомогою міток (labels) контейнерів і за замовчуванням перенаправляє WebSocket upgrades.
Не використовуйте basic-auth для всього vhost, оскільки це заблокує доступ до публічної сторінки статусу та ендпоінту /api/push. Використовуйте вбудовану систему логіну Uptime Kuma, додайте fail2ban watching for repeated failed logins, якщо сервіс доступний з інтернету. Якщо дашборд не має бути публічним, відмовтеся від проксі та використовуйте VPN.
Правильний моніторинг терміну дії сертифікатів
HTTP(s) монітор може попереджати про закінчення терміну дії TLS-сертифіката. Увімкніть параметр Certificate Expiry Notification, і Uptime Kuma надішле сповіщення за вказану кількість днів. Існують дві помилки, через які моніторинг працює некоректно. Використовуйте для моніторингу hostname, а не IP. Якщо запит не містить SNI, сервер поверне сертифікат за замовчуванням, і ви отримаєте помилку Hostname/IP does not match certificate's altnames. Також не вмикайте параметр Ignore TLS/SSL Error для моніторів, для яких потрібні сповіщення про термін дії сертифіката. Цей перемикач призначений для внутрішніх хостів із самопідписаними сертифікатами (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT), але він повністю вимикає перевірку сертифіката в Uptime Kuma, включаючи перевірку терміну дії.
Backups: це одна директорія
Оскільки всі дані зберігаються в /app/data, резервна копія — це копія цього тому, зроблена під час зупиненого контейнера. Це забезпечує цілісність файлу SQLite:
cd /srv/uptime-kuma
sudo docker compose stop
sudo docker run --rm \
-v uptime-kuma_kuma-data:/data \
-v /var/backups/kuma:/backup \
alpine tar czf /backup/kuma-$(date -u +%Y%m%dT%H%M%SZ).tgz -C /data .
sudo docker compose startСпочатку перевірте справжню назву тому за допомогою docker volume ls | grep kuma, оскільки Compose додає префікс назви робочого каталогу. Потім скопіюйте архів на інший пристрій, оскільки резервна копія на тому самому VPS є лише копією, а не справжнім бекапом. Процес відновлення зворотний: зупиніть стек, розпакуйте дані у порожній том /app/data і запустіть стек.
Upgrades
Оновлення виконуються шляхом завантаження нового образу (image pull):
cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -dПри першому запуску новий контейнер виконує міграцію бази даних; стежте за docker compose logs -f. Зробіть резервну копію, вказану вище, перед завантаженням образу. Залишайтеся в межах одного мажорного тегу: перехід від :1 до :2 є односторонньою міграцією, тому спочатку зробіть резервну копію та перевірте примітки до релізу.
Режими відмови та відповідні повідомлення
Хибний статус "down" для монітора, націленого на localhost. Монітор стає червоним з помилкою timeout of 48000ms exceeded або connect ETIMEDOUT, хоча сервіс відповідає на вашому ноутбуці. Якщо монітор націлений на той самий хост, де запущено Uptime Kuma, причиною є стрибок завантаження CPU або пам'яті, що завадив перевірці, а не недоступність цілі. Перенесіть монітор на окремий VPS і використовуйте публічне ім'я хоста.
connect ECONNREFUSED 127.0.0.1:443 (або будь-який інший порт). На цьому порту немає активних прослуховувань: або сервіс вимкнено, або ви моніторили localhost всередині контейнера, де 127.0.0.1 — це контейнер, а не ваш сервер. Використовуйте публічне ім'я хоста замість loopback.
Invalid login: 535-5.7.8 Username and Password not accepted під час тестування пошти. Неправильні облікові дані SMTP, або провайдер вимагає пароль додатка, а ви вказали пароль від облікового запису. Згенеруйте пароль додатка і вставте його.
connect ETIMEDOUT або queryA ETIMEDOUT <host> під час тестування пошти. Неправильний порт або провайдер блокує вихідний SMTP. Переконайтеся, що 465 або 587 відповідає налаштуванням Secure/STARTTLS, і протестуйте з хоста за допомогою nc -vz smtp.example.com 587. Багато провайдерів блокують вихідний 25, а деякі блокують порти відправки (submission) до запиту.
self signed certificate або unable to verify the first certificate під час тестування пошти. Ваш SMTP-сервер використовує сертифікат, якому Node не довіряє; виправте сертифікат поштового сервера замість того, щоб ігнорувати помилку.
Панель зависла на стані "Connecting...", у консолі відображається WebSocket connection ... failed. Reverse proxy не виконує upgrade протоколу до WebSocket. Додайте заголовки Upgrade та Connection "upgrade" у nginx або використовуйте проксі, який пересилає їх за замовчуванням, наприклад Traefik або Caddy. HTML завантажується, оскільки це звичайний HTTP GET; upgrade потрібен лише для live-сокета.
Монітор терміну дії сертифіката не видає попередження або видає помилкові. Або увімкнено опцію Ignore TLS/SSL Error, що вимикає перевірку сертифіката, або монітор націлений на IP-адресу і зчитує невірний сертифікат через відсутність SNI, що призводить до Hostname/IP does not match certificate's altnames. Зніміть галочку ігнорування та використовуйте моніторинг за іменем хоста.
SQLITE_BUSY або database disk image is malformed у логах. Том /app/data знаходиться на файловій системі без належного блокування файлів, зазвичай це NFS; перенесіть його на локальний Docker volume і відновіть з резервної копії.
FAQ
Де мені запускати uptime monitor?
На іншому сервері, ніж ті, які він перевіряє. Ідеально — у іншого провайдера або в іншому регіоні. Доступ до цілей має здійснюватися за hostname через публічний інтернет, так само як це роблять ваші користувачі. Якщо монітор працює на тому ж хості, що й цілі, збій сервера вимкне і монітор. Перевантажений хост може помилково повідомити про "down" сервіси, які насправді працюють. Маленький окремий VPS вирішує обидві проблеми.
Як отримувати сповіщення в Telegram або на email?
Додайте канал у розділі Settings then Notifications, а потім призначте його для кожного монітора. Для Telegram створіть бота за допомогою @BotFather та отримайте chat.id від https://api.telegram.org/bot<token>/getUpdates. Для email використовуйте 465 для SSL або 587 для STARTTLS з паролем додатка, якщо ваш провайдер використовує двофакторну автентифікацію. Натисніть Test і переконайтеся, що повідомлення приходить, перш ніж покладатися на цей метод.
Чи може Uptime Kuma моніторити cron job або скрипт резервного копіювання?
Так, для цього існує тип монітора Push. Uptime Kuma надає URL, який ви curl у кінці скрипта, щоб сповіщення надсилалося лише у разі успішного виконання. Якщо завдання не виконано або сервер вимкнено, heartbeat не надійде, і ви отримаєте сповіщення після закінчення інтервалу. Це єдиний надійний спосіб перевірити виконання запланованого завдання, оскільки зовнішня перевірка не має доступу до внутрішніх процесів.
Uptime Kuma чи Zabbix: що обрати?
Uptime Kuma за 10 хвилин з мінімальним споживанням ресурсів дає відповідь на питання "чи працює сервіс зовні та чи надіслано сповіщення", а також надає сторінку статусу. Він не збирає детальні метрики, такі як динаміка CPU, пам'яті або диска, і не підтримує загальносистемні пороги (thresholds). Для цього повний сервер моніторингу Zabbix є складнішим інструментом на базі агентів; багато користувачів використовують обидва рішення. Ще не визначилися з вибором? наш огляд того, що варто хостити самостійно у 2026 допоможе зорієнтуватися.