Uptime Kuma no Docker para monitorar sites e servidores
Instale o Uptime Kuma com Docker em outro VPS para monitorar sites, portas, DNS e cron, testar alertas por email ou Telegram e publicar uma página de status.
O que você vai criar
Um único contentor pequeno que monitoriza os seus outros servidores e sites a partir do exterior e o informa no momento em que um deles deixa de responder, por email, Telegram, Discord ou um webhook. O Uptime Kuma é um processo Node suportado por um ficheiro SQLite, por isso funciona confortavelmente com 256-512 MB de RAM e disponibiliza um painel em tempo real, gráficos do histórico e uma página pública de estado. A instalação é feita com um ficheiro Compose de dez linhas; o que realmente importa é onde o executa e se os alertas já foram acionados num teste, porque um monitor cuja capacidade de o contactar nunca foi comprovada é pior do que não ter monitor nenhum: cria uma sensação de proteção enquanto não monitoriza nada.
Execute o monitor num local que a interrupção não consiga alcançar
Esta decisão determina se toda a configuração funciona, por isso vem primeiro. Não execute o Uptime Kuma no mesmo servidor que aloja os serviços monitorizados. Se o monitor estiver no servidor que monitoriza, o próprio evento que pretende detetar — esse servidor ficar indisponível ou ficar sem memória — também termina o monitor, e não recebe qualquer alerta: o silêncio de um monitor parado é indistinguível de «está tudo bem». Existe ainda uma armadilha mais subtil enquanto o servidor continua ativo: um monitor que aponta para localhost partilha a CPU com a carga de trabalho. Um pico de carga pode fazer o próprio teste exceder o tempo limite e marcar o destino como indisponível, gerando um falso alerta, enquanto os utilizadores continuam a ser atendidos normalmente.
Por isso, execute o Uptime Kuma num VPS diferente daquele que monitoriza, idealmente num fornecedor ou numa região diferente, acedendo aos serviços da mesma forma que os utilizadores: através da Internet pública e pelo nome de domínio. Uma instância económica é suficiente, e um VPS pequeno de monitorização pode acompanhar todos os seus servidores. Esta separação é especialmente importante para as aplicações pesadas que aloja, porque algo como uma biblioteca de fotografias PhotoPrism ou Immich pode manter a CPU ocupada durante horas ao indexar uma importação recente, e um monitor que partilhe esse hardware pode assinalar como indisponível um serviço que está apenas ocupado. Para detetar uma falha do próprio Kuma, adicione um heartbeat push a partir de um cron noutro local.
Pré-requisitos e dimensionamento
- Um VPS Ubuntu 24.04 novo, com Docker Engine e o plugin Compose v2 instalados a partir do próprio repositório apt do Docker, e não do pacote de distribuição
docker.io, que fica desatualizado. - 256 MB de RAM são suficientes para alguns monitores; 512 MB a 1 GB oferecem uma margem confortável para dezenas de monitores, além do reverse proxy. O uso de CPU fica quase inativo entre verificações.
- Um domínio e um registo DNS
A(por exemplo,status.example.coma apontar para o VPS), apenas se quiser TLS e uma página de estado pública. Uma instância privada pode ignorar o DNS e usar uma VPN ou um túnel SSH. - Acesso de saída à rede para os destinos dos alertas: SMTP para o seu fornecedor de email ou HTTPS para o Telegram e o Discord.
O arquivo Compose
Coloque isto em /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:Inicie o serviço e acompanhe o primeiro arranque:
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-kumaUm arranque correto regista Listening on 3001 e deixa de emitir mensagens. Há três elementos deliberados nesse ficheiro.
127.0.0.1:3001:3001, não 3001:3001. O Docker publica portas com regras DNAT avaliadas antes de o ufw ver o pacote. Por isso, um 3001:3001 simples expõe o dashboard à Internet pública, independentemente da firewall. A ligação à interface de loopback mantém o serviço privado, expondo apenas o reverse proxy. Numa instância privada, pode dispensar o proxy e aceder a 3001 através de uma VPN WireGuard self-hosted.
Um volume nomeado em /app/data. Tudo o que o Uptime Kuma guarda, incluindo a base de dados SQLite, os seus monitores, as definições de notificações e os logótipos das páginas de estado, fica aí. Se o perder, começará com um ecrã de administração vazio. É o único elemento que tem de incluir nas cópias de segurança.
A imagem está fixada numa tag principal, :2. Essa é a linha estável atual. Consulte o Docker Hub para confirmar a versão principal mais recente antes de a copiar. Nunca acompanhe uma tag móvel como latest, que o projeto descontinua. Uma mudança de versão principal nesta imagem é uma migração da base de dados sem retorno. Deve iniciá-la deliberadamente, não encontrá-la por acaso durante uma atualização normal.
Há uma ressalva: /app/data tem de estar num sistema de ficheiros com bloqueios de ficheiros POSIX. Um volume Docker local é adequado. Em NFS, a base de dados SQLite fica corrompida e surgem SQLITE_BUSY e database disk image is malformed. Por isso, nunca utilize uma partilha de rede.
Primeira execução: crie a conta de administrador
Aceda à instância através do proxy em https://status.example.com ou por um túnel SSH: execute ssh -L 3001:127.0.0.1:3001 user@your-vps e abra http://localhost:3001. A primeira página é um formulário de configuração do nome de utilizador e da palavra-passe do administrador; não existe um início de sessão predefinido. Escolha uma palavra-passe segura: este dashboard vê os endereços internos e os tokens de tudo o que monitoriza. Se se esquecer dela mais tarde, faça a reposição no host, não no browser:
sudo docker compose exec uptime-kuma npm run reset-passwordAdicione primeiro os canais de notificação e teste-os
Configure os alertas antes de adicionar monitores, para poder associar um canal ao criar cada um. Aceda a Settings depois Notifications depois Setup Notification e use o botão Test de cada canal para confirmar que a mensagem é recebida, porque uma notificação não testada é a segunda causa mais comum de uma configuração falhar silenciosamente.
Email (SMTP). Preencha o host, a porta, a encriptação, o nome de utilizador, a palavra-passe, um From e um To. As duas combinações funcionais são 465 com a opção "Secure" definida como TLS/SSL ou 587 com STARTTLS. No Gmail e na maioria dos fornecedores com autenticação de dois fatores, é necessário gerar uma app password; uma palavra-passe normal da conta devolve Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Telegram. Envie uma mensagem para @BotFather, envie /newbot e copie o token do bot. Para obter o ID da conversa, envie primeiro uma mensagem ao novo bot, abra https://api.telegram.org/bot<token>/getUpdates e leia chat.id no JSON. Um bot ao qual nunca foi enviada uma mensagem tem um getUpdates vazio e não tem para onde enviar mensagens.
Discord. No canal, abra Edit Channel depois Integrations depois Webhooks depois New Webhook, copie o URL e cole-o como uma notificação Discord.
Webhook genérico. Para qualquer outro serviço, como um webhook de entrada do Slack, um endpoint personalizado ou um webhook de automação doméstica, o tipo Webhook envia uma carga JSON por POST para um URL fornecido por si. A integração Apprise incluída abrange a maioria dos cerca de noventa outros serviços da lista. Se preferir que nenhum terceiro fique entre uma falha e o seu telefone, escolha o tipo integrado ntfy e aponte-o para um servidor ntfy que execute por sua conta, que envia notificações para o seu telefone através de um canal que controla de ponta a ponta.
Adicionar monitores, um tipo de cada vez
Clique em Add New Monitor, escolha um tipo e defina o Friendly Name, o Check Interval (60 segundos é adequado), as Retries (falhas consecutivas antes de marcar como "down"; use 2 ou 3 para que um pacote perdido não gere uma página) e as notificações a enviar. Os tipos que vai utilizar são:
- HTTP(s). Um URL completo. O estado é considerado ativo quando o código de estado é aceite (200-299 por predefinição; alargue o intervalo em Accepted Status Codes se
301ou401for normal no seu caso). É o monitor principal para sites e APIs. - HTTP(s) - Keyword. Faz o mesmo pedido, mas, para ser considerado "up", também exige que uma cadeia de caracteres esteja presente no corpo ou, com Invert, que esteja ausente. Isto deteta quando o site devolve
200 OKmas apresenta a mensagem "Error establishing a database connection", situação que um monitor HTTP simples considera saudável. É também o monitor adequado para um frontend de navegador que comunica com um backend separado, como uma interface Halcyon para uma loja de vídeos sobre Jellyfin, cuja estrutura da página devolve200normalmente enquanto o servidor de multimédia não está acessível. - TCP Port. Uma ligação TCP simples a um host e porta, para serviços que não usam HTTP: SSH na porta 22, Postgres na porta 5432, um servidor SMTP na porta 25 ou um servidor de jogos.
- Ping. Echo ICMP: permite verificar a acessibilidade e a latência com baixo custo. No entanto, muitas redes e firewalls de fornecedores bloqueiam ICMP. Por isso, um monitor Ping em estado de erro pode significar que o host está indisponível ou que o fornecedor bloqueia o ping. Confirme com um monitor TCP.
- DNS. Resolve um registo (A, AAAA, MX, TXT e outros) através de um resolver indicado por si e pode validar a resposta. Isto permite detetar rapidamente uma falha do registrar ou do DNS.
- Push. O monitor que funciona no sentido inverso, descrito na secção seguinte.
Monitorizar um cron job com um monitor push (heartbeat)
Todos os monitores anteriores chegam ao seu serviço a partir do exterior. Um monitor push funciona no sentido inverso: o Uptime Kuma espera, e o seu job chama-o para indicar que foi executado. Esta é a única forma fiável de monitorizar uma cópia de segurança ou um cron: uma verificação HTTP confirma que um URL responde, mas apenas o próprio job sabe se terminou.
Crie um monitor do tipo Push. O Uptime Kuma gera um URL único, semelhante a:
https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=Defina o Heartbeat Interval para a frequência de execução do job, com alguma margem adicional. Depois, adicione uma linha ao fim do script, para que seja executada apenas em caso de sucesso:
#!/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="Se o job falhar, set -e termina antes de executar o curl; se o servidor estiver indisponível, o job também não é executado. Em ambos os casos, o heartbeat para. Quando passar a janela correspondente ao intervalo mais as tentativas, o Uptime Kuma muda o estado do monitor para down e envia um alerta. Trate esse token push como um segredo: qualquer pessoa que o possua pode forjar um heartbeat saudável.
Crie uma página de estado pública
Uma página de estado é a vista apresentada aos clientes: mostra quais serviços estão operacionais e o respetivo histórico recente, sem expor o seu painel. Aceda a Status Pages e depois New Status Page, atribua-lhe um nome e um slug (o caminho público, como /status/main), arraste os monitores pretendidos para grupos como "Websites" e "APIs", adicione um logótipo e uma descrição curta e selecione Save. Também pode associar a página ao seu próprio domínio para que status.example.com a disponibilize diretamente.
Tenha em atenção dois pontos: adicione apenas monitores que esteja disposto a tornar públicos, porque uma página de estado revela que um serviço existe e se está operacional; o painel continua protegido pelo seu login, enquanto a página de estado é deliberadamente pública e não requer autenticação.
Coloque atrás de um reverse proxy com TLS e tenha atenção aos WebSockets
Para uma instância pública, coloque um reverse proxy à frente do contentor ligado ao loopback para fornecer TLS e um nome de host. O detalhe que causa mais problemas: a interface do Uptime Kuma é uma aplicação Socket.IO em tempo real, por isso o proxy tem de atualizar a ligação WebSocket. Se isso for omitido, a página carrega, mas nunca estabelece ligação; o dashboard fica em "Connecting...", os heartbeats em tempo real nunca são atualizados e a consola do navegador mostra WebSocket connection to 'wss://.../socket.io/...' failed.
Instale nginx e certbot. Depois, escreva o vhost que encaminha os pedidos para a porta de loopback. Use a porta 80 por enquanto e deixe o certbot adicionar o TLS depois; o desafio, o temporizador de renovação e os respetivos modos de falha são abordados em emitir certificados Let's Encrypt com certbot e nginx.
sudo apt install -y nginx certbot python3-certbot-nginxGuarde isto como /etc/nginx/sites-available/status.example.com; as duas linhas de WebSocket são as importantes:
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;
}
}Ative o site e teste a configuração. Depois, deixe o certbot reescrever o bloco para escutar na porta 443, instalar o certificado e adicionar um redirecionamento de HTTP para HTTPS:
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.comO par Upgrade e Connection "upgrade" é o essencial, e proxy_read_timeout 3600s impede que o nginx termine a ligação persistente; o certbot copia ambos para o bloco da porta 443 que gera. Se já executa vários contentores atrás de um único proxy, encaminhá-los através do Traefik com TLS automático faz o mesmo com labels de contentores e encaminha atualizações WebSocket por predefinição.
Não use autenticação básica em todo o vhost, porque isso também bloqueia a página pública de estado e o endpoint /api/push. Mantenha o login integrado do Uptime Kuma. Adicione fail2ban para monitorizar tentativas de login falhadas repetidas se o serviço estiver exposto à Internet. Se o dashboard nunca precisar de ser público, remova o proxy e aceda a ele através de uma VPN.
Monitorização da expiração de certificados, feita corretamente
Um monitor HTTP(s) também pode avisá-lo antes de um certificado TLS expirar: ative Certificate Expiry Notification e o Uptime Kuma enviará um alerta com o número de dias definido de antecedência. Dois erros fazem com que a leitura fique incorreta. Monitorize pelo hostname, não pelo IP, ou um pedido sem SNI receberá o certificado predefinido do servidor e verá Hostname/IP does not match certificate's altnames. Não ative Ignore TLS/SSL Error num monitor do qual pretende receber avisos de expiração: essa opção destina-se a hosts internos com certificados autoassinados (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT), mas impede o Uptime Kuma de verificar o certificado, incluindo a respetiva expiração.
Backups: é um diretório
Como tudo está em /app/data, um backup é uma cópia desse volume feita enquanto o contentor está parado. Assim, o ficheiro SQLite fica consistente:
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 startConfirme primeiro o nome real do volume com docker volume ls | grep kuma, porque o Compose acrescenta o prefixo do diretório do projeto. Depois copie o tarball para fora do servidor, porque um backup no mesmo VPS é apenas uma cópia, não um backup. A restauração funciona no sentido inverso: pare a stack, extraia os ficheiros para um volume /app/data vazio e inicie-a.
Atualizações
As atualizações consistem em obter uma nova imagem:
cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -dO novo contentor executa qualquer migração da base de dados no primeiro arranque; monitorize docker compose logs -f. Faça a cópia de segurança indicada acima antes de obter a imagem e mantenha-se dentro da mesma tag principal: passar de :1 para :2 é uma migração unidirecional, por isso faça primeiro uma cópia de segurança e consulte as notas da versão.
Modos de falha e as mensagens apresentadas
Estado "down" incorreto num monitor que aponta para localhost. O monitor fica vermelho com timeout of 48000ms exceeded ou connect ETIMEDOUT, mas o serviço responde a partir do seu portátil. Se o monitorizar o mesmo host onde o Uptime Kuma é executado, um pico de CPU ou memória impediu a verificação, e não o destino. Mova o monitor para um VPS separado e use o hostname público como destino.
connect ECONNREFUSED 127.0.0.1:443 (ou qualquer outra porta). Não havia nenhum processo a escutar nessa porta. O serviço está parado ou monitorizou localhost a partir do interior do contentor, onde 127.0.0.1 é o contentor, e não o seu servidor. Monitorize o hostname público, e não o loopback.
Invalid login: 535-5.7.8 Username and Password not accepted num teste de email. As credenciais SMTP estão erradas ou o fornecedor exige uma palavra-passe específica da aplicação, mas foi usada a palavra-passe da conta. Gere uma palavra-passe de aplicação e introduza-a.
connect ETIMEDOUT ou queryA ETIMEDOUT <host> num teste de email. A porta está errada ou o fornecedor bloqueia SMTP de saída. Confirme se 465 ou 587 corresponde à definição Secure/STARTTLS e teste a partir do host com nc -vz smtp.example.com 587. Muitos fornecedores bloqueiam 25 de saída e alguns bloqueiam as portas de submissão até que seja feito um pedido de desbloqueio.
self signed certificate ou unable to verify the first certificate num teste de email. O servidor SMTP apresenta um certificado que o Node não considera fiável. Corrija o certificado do servidor de email em vez de contornar o problema.
O dashboard fica preso em "Connecting..." e a consola apresenta WebSocket connection ... failed. O reverse proxy não está a fazer o upgrade do WebSocket. Adicione os cabeçalhos Upgrade e Connection "upgrade" no nginx ou use um proxy que os encaminhe por predefinição, como Traefik ou Caddy. O HTML é carregado porque corresponde a um GET HTTP normal. Apenas o socket ativo precisa do upgrade.
O monitor de expiração de certificados nunca avisa ou avisa incorretamente. A opção Ignore TLS/SSL Error está selecionada, o que desativa a verificação do certificado, ou o monitor aponta para um IP e lê o certificado errado porque falta SNI, apresentando Hostname/IP does not match certificate's altnames. Desmarque a opção de ignorar erros e monitorize pelo hostname.
SQLITE_BUSY ou database disk image is malformed nos logs. O volume /app/data está num sistema de ficheiros sem bloqueio correto de ficheiros, normalmente NFS. Mova-o para um volume Docker local e restaure-o a partir da cópia de segurança.
FAQ
Onde devo executar o meu monitor de disponibilidade?
Num servidor diferente dos servidores monitorizados, idealmente noutro provedor ou noutra região, acedendo a eles pelo nome de host através da Internet pública, tal como os seus utilizadores fazem. Se o monitor partilhar um servidor com os destinos, a falha que interromper o servidor também interromperá o monitor, e um host sobrecarregado fará com que ele indique "down" para serviços que estão a funcionar. Um VPS separado e pequeno evita ambos os problemas.
Como recebo alertas no Telegram ou por email?
Adicione o canal em Settings then Notifications e associe-o a cada monitor. Para o Telegram, crie um bot com @BotFather e leia chat.id a partir de https://api.telegram.org/bot<token>/getUpdates; para email, use 465 para SSL ou 587 para STARTTLS, com uma palavra-passe de aplicação se o seu provedor usar autenticação de dois fatores. Prima Test e confirme que a mensagem chega antes de depender dela.
O Uptime Kuma pode monitorizar um cron job ou um script de backup?
Sim. Esse é o monitor Push: o Uptime Kuma fornece um URL e o script deve executar curl no fim, para que o monitor seja acionado apenas quando o script terminar com sucesso. Se o job falhar ou o servidor estiver indisponível, o heartbeat nunca chega e receberá um alerta depois de passar o intervalo configurado. É a única forma fiável de confirmar que um job agendado foi realmente executado, porque uma verificação externa não consegue ver o que acontece dentro dele.
Uptime Kuma ou Zabbix: qual devo executar?
O Uptime Kuma responde a "está disponível externamente e enviou-me um alerta?" em dez minutos, com consumo quase nulo de recursos e uma página de estado. Não recolhe métricas detalhadas, como tendências de CPU, memória e disco, nem aplica limites a toda a frota; para isso, um servidor de monitorização Zabbix completo é a ferramenta mais pesada, baseada em agentes, e muitas pessoas executam ambos. Ainda não decidiu o que executar? o nosso resumo do que alojar autonomamente em 2026 contextualiza a monitorização.