SSD Nodes Learn
Guias Matt ConnorPor Matt Connor · Atualizado 2026-07-24

Como instalar Uptime Kuma no Docker

Monitore sites, portas e DNS com Uptime Kuma via Docker. Configure alertas por Telegram ou email e publique páginas de status usando um arquivo docker-compose.

O que você está construindo

Um único container pequeno que monitora seus outros servidores e sites externamente. Ele avisa no momento em que um serviço para de responder via email, Telegram, Discord ou webhook. O Uptime Kuma é um processo Node com suporte de um arquivo SQLite. Ele roda com facilidade em 256-512 MB de RAM e oferece um dashboard em tempo real, gráficos de histórico e uma página de status pública. A instalação consiste em um arquivo Compose de dez linhas. O que realmente importa é onde você o executa e se seus alertas funcionaram em um teste. Um monitor que você nunca testou se ele consegue te avisar é pior do que não ter monitor nenhum: ele gera uma falsa sensação de segurança enquanto você não recebe nada.

Execute o monitor em um local que a interrupção não possa alcançar

Esta decisão define o sucesso ou o fracasso de todo o sistema, por isso deve ser a primeira. Não execute o Uptime Kuma na mesma máquina que ele monitora. Se o monitor estiver no servidor monitorado, o evento que você deseja detectar (como a queda do servidor ou falta de memória) também derrubará o monitor. Isso impede o recebimento de alertas, pois o silêncio de um monitor offline é indistinguível de um estado de "tudo funcionando". Existe uma armadilha mais sutil enquanto o servidor ainda está ativo: um monitor apontado para localhost compartilha a CPU com a carga de trabalho. Um pico de carga pode causar timeout na verificação e marcar o alvo como down (falso positivo), enquanto os usuários reais continuam sendo atendidos normalmente.

Portanto, execute o Uptime Kuma em um VPS diferente daquele que ele monitora. O ideal é usar um provedor ou região distintos, acessando seus serviços da mesma forma que seus usuários: via internet pública, por hostname. Uma instância barata é suficiente, e um único VPS de monitoramento pode vigiar todos os seus servidores. Para detectar se o próprio Kuma falhar, adicione um push heartbeat via cron em outro local.

Pré-requisitos e dimensionamento

  • Um VPS Ubuntu 24.04 recém-instalado com Docker Engine e o plugin Compose v2, instalados via repositório apt oficial do Docker, não pelo pacote da distro docker.io, que é desatualizado.
  • 256 MB de RAM executam alguns monitores; 512 MB a 1 GB é o ideal para dezenas de monitores e o reverse proxy, com uso de CPU próximo a zero entre as verificações.
  • Um domínio e um registro DNS A (ex: status.example.com apontando para o VPS), apenas se você desejar TLS e uma página de status pública. Uma instância privada pode ignorar o DNS e usar uma VPN ou túnel SSH.
  • Conexão de rede de saída para o destino dos alertas: SMTP para seu provedor de e-mail, ou HTTPS para Telegram e 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 container e acompanhe o primeiro boot:

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

Um início correto exibe logs de Listening on 3001 e para de registrar mensagens. Três itens neste arquivo são deliberados.

127.0.0.1:3001:3001, não 3001:3001. O Docker publica portas com regras DNAT avaliadas antes do ufw processar o pacote. Portanto, um 3001:3001 expõe seu dashboard para a internet pública, independentemente do seu firewall. Vincular ao loopback mantém o acesso privado, expondo apenas o reverse proxy; uma instância privada pode ignorar o proxy e acessar 3001 via uma VPN WireGuard self-hosted em vez disso.

Um volume nomeado em /app/data. Tudo o que o Uptime Kuma armazena — o banco de dados SQLite, seus monitores, configurações de notificação e logotipos da página de status — reside ali. Se perder esse volume, você voltará para uma tela de admin vazia; este é o único item que você deve fazer backup.

A imagem está fixada em uma tag de versão principal, :2. Esta é a linha estável atual; verifique o Docker Hub para a versão principal mais recente antes de copiar, e nunca utilize tags mutáveis como latest, que o projeto desaconselha. Um salto de versão principal nesta imagem resulta em uma migração de banco de dados unidirecional; você deve disparar isso deliberadamente, não por acidente durante um pull de rotina.

Uma observação: /app/data deve estar em um filesystem com travas de arquivo (file locks) POSIX. Um volume Docker local funciona bem; em NFS, o banco de dados SQLite corrompe e você terá SQLITE_BUSY e database disk image is malformed, portanto, nunca use um compartilhamento de rede.

Primeira execução: criar a conta de administrador

Acesse a instância através do seu proxy em https://status.example.com, ou via 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 para o nome de usuário e senha do administrador; não existe login padrão. Escolha uma senha real: este dashboard visualiza os endereços internos e tokens de tudo o que você monitora. Esqueceu a senha? Redefina pelo host, não pelo navegador:

sudo docker compose exec uptime-kuma npm run reset-password

Primeiro adicione seus canais de notificação e teste-os

Configure os alertas antes de adicionar os monitores. Isso permite anexar um canal durante a criação de cada monitor. Vá em Settings then Notifications then Setup Notification e use o botão Test de cada canal para confirmar o recebimento da mensagem. Uma notificação não testada é a segunda causa mais comum de falhas silenciosas na configuração.

Email (SMTP). Preencha host, port, encryption, username, password, um From e um To. As duas combinações funcionais são 465 com "Secure" definido como TLS/SSL, ou 587 com STARTTLS. Para Gmail e a maioria dos provedores com autenticação de dois fatores, você deve gerar uma app password; uma senha de conta comum retorna Error: Invalid login: 535-5.7.8 Username and Password not accepted.

Telegram. Envie uma mensagem para @BotFather, envie /newbot e copie o bot token. Para o seu chat ID, envie uma mensagem para o novo bot, abra https://api.telegram.org/bot<token>/getUpdates e leia chat.id no JSON. Um bot para o qual você nunca enviou mensagem possui um getUpdates vazio e não tem para onde enviar.

Discord. No canal, abra Edit Channel then Integrations then Webhooks then New Webhook, copie a URL e cole-a como uma notificação do Discord.

Generic webhook. Para qualquer outro serviço, como um incoming webhook do Slack, um endpoint customizado ou um hook de automação residencial, o tipo Webhook envia um payload JSON via POST para a URL fornecida. A integração Apprise inclusa suporta a maioria dos outros noventa serviços da lista.

Adicione monitores, um tipo por vez

Clique em Add New Monitor, escolha um tipo e defina o Friendly Name, o Check Interval (60 segundos é um valor seguro), o Retries (falhas consecutivas antes de marcar como "down"; use 2 ou 3 para evitar alertas por um único pacote perdido) e as notificações para disparar. Os tipos que você utilizará:

  • HTTP(s). Uma URL completa. "Up" significa um status code aceitável (200-299 por padrão; aumente o intervalo em Accepted Status Codes se 301 ou 401 for normal para você). É a ferramenta principal para sites e APIs.
  • HTTP(s) - Keyword. A mesma requisição, mas "up" também exige que uma string esteja presente no corpo (ou ausente, se Invert estiver marcado). Isso detecta quando o site retorna 200 OK enquanto exibe "Error establishing a database connection", o que um check HTTP simples consideraria saudável.
  • TCP Port. Uma conexão TCP direta para um host e porta, para serviços que não são HTTP: SSH na 22, Postgres na 5432, um servidor SMTP na 25, ou um servidor de jogo.
  • Ping. ICMP echo: baixo custo para verificar conectividade e latência. Porém, muitas redes e firewalls de nuvem descartam ICMP, então um monitor de ping em vermelho pode significar "host offline" ou "provedor bloqueia ping"; confirme com um monitor TCP.
  • DNS. Resolve um registro (A, AAAA, MX, TXT, etc.) contra um resolver definido por você, e pode validar a resposta, detectando falhas de registro ou de DNS precocemente.
  • Push. O monitor "inside-out", detalhado a seguir.

Monitorando um cron job com um monitor de push (heartbeat)

Todos os monitores acima acessam seu serviço de fora para dentro. Um monitor de push funciona de forma inversa: o Uptime Kuma aguarda, e o seu job o chama para avisar que foi executado. Esta é a única forma confiável de monitorar um backup ou cron: um check de HTTP sabe se uma URL responde, mas apenas o job sabe se a tarefa foi concluída.

Crie um monitor do tipo Push. O Uptime Kuma gera uma URL única como:

https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=

Defina o Heartbeat Interval com a frequência de execução do job, somando uma pequena margem de segurança. Em seguida, adicione uma linha ao final do script para que o envio ocorra 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, o set -e aborta antes do curl; se o servidor estiver offline, o script também não será executado. Em ambos os casos, o heartbeat para e, após o intervalo definido mais as tentativas de reenvio, o Uptime Kuma altera o status do monitor para down e envia um alerta. Trate esse push token como uma credencial secreta: qualquer pessoa com o token pode simular um status saudável.

Crie uma página de status pública

Uma página de status é a visualização voltada para o cliente: mostra quais serviços estão ativos e o histórico recente, sem expor o seu dashboard. Vá em Status Pages then New Status Page, defina um nome e um slug (o caminho público, como /status/main), arraste os monitores desejados para grupos como "Websites" e "APIs", adicione um logo e uma descrição curta, e clique em Save. Você também pode vincular a página ao seu próprio domínio para que o status.example.com a sirva diretamente.

Duas precauções: adicione apenas monitores que você deseja tornar públicos, pois uma página de status revela a existência de um serviço e se ele está online; e o dashboard permanece protegido pelo seu login, enquanto a página de status é intencionalmente pública e não requer autenticação.

Configure um reverse proxy com TLS e atenção aos websockets

Para uma instância pública, utilize um reverse proxy à frente do container vinculado ao loopback para obter TLS e um hostname. O detalhe que causa erros: a UI do Uptime Kuma é um app Socket.IO em tempo real, portanto o proxy deve realizar o upgrade da conexão WebSocket. Se ignorar isso, a página carregará mas não conectará; o dashboard ficará travado em "Connecting...", os heartbeats não atualizarão e o console do navegador exibirá WebSocket connection to 'wss://.../socket.io/...' failed.

Instale o nginx e o certbot, depois escreva o vhost que faz o proxy para a porta de loopback. Configure na porta 80 por enquanto e deixe o certbot adicionar o TLS depois; os detalhes sobre o desafio, o timer de renovação e seus modos de falha estão cobertos em issuing Let's Encrypt certificates with certbot and nginx.

sudo apt install -y nginx certbot python3-certbot-nginx

Salve este arquivo como /etc/nginx/sites-available/status.example.com; as duas linhas de WebSocket são as mais 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;
    }
}

Habilite o site, teste a configuração e deixe o certbot reescrever o bloco para escutar na porta 443, inserindo o certificado e adicionando 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.com

O par Upgrade e Connection "upgrade" é o ponto principal, e proxy_read_timeout 3600s impede que o nginx encerre o socket de longa duração; o certbot copia ambos para o bloco 443 que ele gera. Se você já executa vários containers atrás de um único proxy, routing them through Traefik with automatic TLS faz o mesmo usando labels de container e encaminha upgrades de WebSocket por padrão.

Não utilize basic-auth em todo o vhost, pois isso bloqueia a página de status pública e o endpoint /api/push. Mantenha o login nativo do Uptime Kuma, adicione fail2ban watching for repeated failed logins se o serviço estiver exposto à internet e, se o dashboard não precisar ser público, remova o proxy e acesse via VPN.

Monitoramento de expiração de certificado de forma correta

Um monitor HTTP(s) também pode avisar antes de um certificado TLS expirar: marque Certificate Expiry Notification e o Uptime Kuma enviará alertas com um número definido de dias de antecedência. Dois erros causam leituras incorretas. Monitore por hostname, não por IP, caso contrário uma requisição sem SNI receberá o certificado padrão do servidor e você verá Hostname/IP does not match certificate's altnames. Além disso, não marque Ignore TLS/SSL Error em um monitor do qual você deseja alertas de expiração: essa opção é para hosts internos com certificados autoassinados (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT), mas ela impede que o Uptime Kuma verifique o certificado, inclusive a validade.

Backups: é apenas um diretório

Como tudo reside em /app/data, o backup é uma cópia desse volume feita com o container parado, garantindo a consistência do arquivo 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

Primeiro, confirme o nome real do volume com docker volume ls | grep kuma, pois o Compose adiciona o prefixo do diretório do projeto. Em seguida, copie o tarball para fora do servidor, pois um backup no mesmo VPS é apenas uma cópia, não um backup. Para restaurar, faça o inverso: pare a stack, extraia os arquivos em um volume /app/data vazio e inicie a stack.

Upgrades

Upgrades consist of um image pull:

cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -d

O novo container executa qualquer database migration no primeiro start; monitore docker compose logs -f. Realize o backup mencionado acima antes do pull. Mantenha-se dentro de uma major tag: a transição de :1 para :2 é uma migration unidirecional; portanto, faça o backup primeiro e verifique as release notes.

Modos de falha e as strings que você verá

Falso "down" em um monitor apontado para localhost. O monitor fica vermelho com timeout of 48000ms exceeded ou connect ETIMEDOUT, mas o serviço responde ao seu laptop. Se o monitor aponta para o mesmo host onde o Uptime Kuma está rodando, um pico de CPU ou memória causou a falha na verificação, não o alvo. Mova o monitor para um VPS separado e aponte para o hostname público.

connect ECONNREFUSED 127.0.0.1:443 (ou qualquer porta). Nada estava escutando nessa porta: ou o serviço está offline, ou você monitorou localhost de dentro do container, onde 127.0.0.1 é o container, não o seu servidor. Monitore o hostname público, não o loopback.

Invalid login: 535-5.7.8 Username and Password not accepted em um teste de e-mail. As credenciais SMTP estão incorretas, ou o provedor exige uma senha de aplicativo e recebeu a senha da sua conta. Gere uma senha de aplicativo e utilize-a.

connect ETIMEDOUT ou queryA ETIMEDOUT <host> em um teste de e-mail. Porta incorreta, ou o provedor bloqueia SMTP de saída. Confirme se 465 ou 587 coincide com a configuração Secure/STARTTLS, e teste a partir do host com nc -vz smtp.example.com 587. Muitos provedores bloqueiam 25 de saída e alguns bloqueiam portas de submission até que você solicite.

self signed certificate ou unable to verify the first certificate em um teste de e-mail. Seu servidor SMTP apresenta um certificado que o Node não confia; corrija o certificado do servidor de e-mail em vez de apenas ignorar o erro.

Dashboard travado em "Connecting...", console mostra WebSocket connection ... failed. O reverse proxy não está realizando o upgrade do WebSocket. Adicione os headers Upgrade e Connection "upgrade" no nginx, ou use um proxy que os encaminhe por padrão, como Traefik ou Caddy. O HTML carrega porque é um HTTP GET normal; apenas o socket em tempo real precisa do upgrade.

Monitor de expiração de certificado nunca avisa, ou avisa incorretamente. Ou a opção Ignore TLS/SSL Error está marcada, o que desativa a verificação do certificado, ou o monitor aponta para um IP e lê o certificado errado por falta de SNI, exibindo Hostname/IP does not match certificate's altnames. Desmarque a opção de ignorar e monitore pelo hostname.

SQLITE_BUSY ou database disk image is malformed nos logs. O volume /app/data está em um filesystem sem suporte a file locking adequado, geralmente NFS; mova-o para um volume Docker local e restaure o backup.

FAQ

Onde devo executar meu monitor de uptime?

Em um servidor diferente dos que ele monitora, idealmente em outro provedor ou região, acessando-os via hostname pela internet pública, da mesma forma que seus usuários fazem. Se o monitor compartilhar o mesmo servidor que os alvos, uma queda que derrube o servidor também derrubará o monitor, e um host sobrecarregado gerará alertas de "down" para serviços que estão funcionando. Uma pequena VPS separada evita ambos os problemas.

Como recebo alertas no Telegram ou por e-mail?

Adicione o canal em Settings then Notifications e vincule-o a cada monitor. Para Telegram, crie um bot com @BotFather e obtenha o chat.id em https://api.telegram.org/bot<token>/getUpdates; para e-mail, use 465 para SSL ou 587 para STARTTLS com uma app password se o seu provedor usar autenticação de dois fatores. Clique em Test e confirme se a mensagem chega antes de confiar no sistema.

O Uptime Kuma pode monitorar um cron job ou script de backup?

Sim, esse é o monitor do tipo Push: o Uptime Kuma fornece uma URL e você a curl ao final do script para que o alerta ocorra apenas em caso de sucesso. Se o job falhar ou o servidor estiver offline, o heartbeat nunca chegará e você será alertado após o intervalo definido. É a única maneira confiável de saber se um job agendado realmente foi executado, já que uma verificação externa não consegue enxergar o que ocorre dentro dele.

Uptime Kuma vs Zabbix, qual devo usar?

O Uptime Kuma responde "está online, externamente, e me alertou?" em dez minutos com quase nenhum recurso, além de oferecer uma página de status. Ele não coleta métricas detalhadas como tendências de CPU, memória e disco ou limites para toda a frota; para isso, um servidor de monitoramento Zabbix completo é a ferramenta mais pesada e baseada em agentes, e muitas pessoas utilizam ambos. Ainda está decidindo o que rodar? nosso resumo do que hospedar você mesmo em 2026 contextualiza o monitoramento.

#uptime-kuma#monitoring#docker#self-hosting#status-page