Gatus no Ubuntu: monitoramento como código com Docker

Mascote LinuxPro acompanhando um painel de monitoramento do Gatus

Um endpoint pode continuar “de pé” para o servidor e, ainda assim, falhar para quem usa o produto. O Gatus é um monitoramento self-hosted orientado a desenvolvedores: você descreve em YAML o que precisa ser verificado, ele executa as sondas, mantém uma página de status e pode alertar quando uma condição deixa de ser verdadeira. Neste primeiro artigo, a meta é simples: subir o Gatus no Ubuntu com Docker, persistir o histórico em SQLite e criar o primeiro check. As opções mais avançadas ficam para um próximo guia.

O que é o Gatus

Gatus é um projeto open source sob licença Apache-2.0, desenvolvido em Go. Ele verifica serviços por HTTP, ICMP, TCP e DNS e não se limita a “a URL respondeu?”: as condições podem validar código HTTP, tempo de resposta, corpo retornado, expiração de certificado e outros valores da sonda. O resultado aparece em um dashboard/página de status e pode alimentar alertas.

O ponto central é a configuração como código. Em vez de cadastrar checks apenas em uma interface, os endpoints vivem em YAML. Isso facilita revisão em pull request, histórico no Git e repetição da mesma política entre ambientes. Se sua preferência for uma interface para criar monitores manualmente, leia também nosso guia de Uptime Kuma no Linux.

Go: por que a linguagem importa

O código do Gatus é escrito em Go. Na prática, isso explica por que ele pode ser distribuído como um executável único e por que a imagem oficial faz uma compilação Go antes de iniciar um binário no contêiner. Para quem opera o serviço com Docker, não há runtime Go para instalar no Ubuntu: a imagem já entrega a aplicação. Para quem escolher a instalação sem contêiner, o próprio projeto documenta go install github.com/TwiN/gatus/v5@latest.

Isso não é garantia automática de baixo consumo em qualquer cenário: quantidade de endpoints, intervalo das sondas, retenção do histórico e banco escolhido continuam definindo a carga. Mas a ausência de uma VM de linguagem no processo de produção torna o modelo operacional direto.

Por que ele encontra falhas antes do usuário

Métricas de uma aplicação podem parecer normais quando nenhum cliente está chegando até ela. Se um balanceador, DNS ou rota externa falha, talvez nem exista tráfego para gerar erro. O Gatus faz uma requisição ativa no intervalo configurado e avalia a resposta. Assim, ele pode avisar que o fluxo público está quebrado antes de o primeiro chamado chegar.

Não é substituto de métricas, logs e tracing. Para CPU, memória, disco e investigação de um servidor Linux, complemente a estratégia com Prometheus e Node Exporter. Pense no Gatus como uma verificação sintética de disponibilidade e de contrato: “este endpoint importante devolve o que prometeu?”.

Instale Docker, Compose e Nginx no Ubuntu

Em um Ubuntu novo, instale o Docker pelo repositório oficial e o Nginx pelo APT. Se a máquina já executa contêineres, revise os pacotes instalados antes de trocar docker.io, containerd ou runc: misturar origens pode causar conflito.

sudo apt update
sudo apt install -y ca-certificates curl nginx
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker nginx
sudo docker run hello-world
docker compose version

O teste hello-world confirma que o daemon está funcionando. Mantenha sudo nos comandos Docker ou trate a entrada no grupo docker como acesso administrativo ao host.

Antes de instalar

Este guia usa Docker Engine e o plugin Docker Compose no Ubuntu. Se ainda não os tiver, siga a instalação pelo repositório oficial do Docker no nosso artigo de Uptime Kuma. Usaremos a porta 8080 ligada somente a 127.0.0.1: isso é seguro para o primeiro teste no servidor e evita publicar o painel sem HTTPS e controle de acesso.

O README oficial também documenta a instalação via Go com go install github.com/TwiN/gatus/v5@latest. Vamos deliberadamente usar Docker neste post para manter a instalação curta e reprodutível. A instalação via Go, proxy reverso, autenticação e bancos externos merecem um tutorial separado.

Suba o Gatus com Docker Compose

Crie os diretórios. O diretório config guarda a definição versionável dos checks; data receberá o SQLite, que preserva o histórico após reinicializações.

sudo install -d -m 0755 /opt/gatus/config /opt/gatus/data
sudo chown -R "$USER":"$USER" /opt/gatus
cd /opt/gatus

Crie compose.yaml:

services:
  gatus:
    image: ghcr.io/twin/gatus:stable
    container_name: gatus
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      GATUS_CONFIG_PATH: /config/config.yaml
    volumes:
      - ./config:/config:ro
      - ./data:/data

A tag stable é a indicada pelo início rápido oficial, mas ela acompanha mudanças. Para produção, teste uma release e fixe uma tag de versão conhecida quando sua política exigir previsibilidade.

Escreva o primeiro monitor

Crie /opt/gatus/config/config.yaml. Este exemplo monitora a página inicial e exige HTTP 200, resposta em menos de dois segundos e certificado válido por mais de sete dias:

storage:
  type: sqlite
  path: /data/data.db

endpoints:
  - name: LinuxPro
    group: site-publico
    url: "https://www.linuxpro.com.br/"
    interval: 5m
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 2000"
      - "[CERTIFICATE_EXPIRATION] > 168h"

Altere URL, nome e limites para o seu serviço. Um limite de dois segundos pode não fazer sentido para toda aplicação; o objetivo é transformar uma expectativa real em uma condição. Para uma API JSON, o Gatus também permite validar um campo do corpo, por exemplo [BODY].status == UP, quando esse contrato existir.

Escolha do banco: memória, SQLite ou PostgreSQL

O Gatus aceita três tipos de armazenamento: memory, sqlite e postgres. MySQL/MariaDB não é um backend suportado pelo Gatus neste momento; não adianta subir um contêiner MySQL e apontar a configuração para ele.

  • Memory: é o padrão e serve apenas para demonstração. Todo histórico some ao reiniciar o processo.
  • SQLite: é a melhor escolha para uma única instância, poucos ou médios conjuntos de endpoints e operação simples. O Compose deste guia já o usa; mantenha ./data em disco local e faça backup do arquivo data.db.
  • PostgreSQL: escolha quando o histórico crescer, quando já existir PostgreSQL gerenciado pela equipe ou quando precisar separar o banco do contêiner da aplicação. Para dashboards grandes, o Gatus oferece storage.caching: true em SQLite e PostgreSQL.

O Compose inicial deste artigo é o cenário SQLite: o volume ./data:/data e storage.type: sqlite no YAML são o “docker-compose para SQLite”. Não remova essas duas partes, ou você volta ao armazenamento em memória.

Docker Compose com PostgreSQL

Quando SQLite deixar de ser suficiente, use um banco PostgreSQL isolado na mesma rede Docker. Crie um arquivo .env com uma senha forte e não o envie ao Git:

POSTGRES_DB=gatus
POSTGRES_USER=gatus
POSTGRES_PASSWORD=troque-por-uma-senha-longa

Depois substitua o compose.yaml pelo exemplo abaixo. PostgreSQL não publica porta no host: somente o contêiner Gatus conversa com ele.

services:
  postgres:
    image: postgres:18
    restart: unless-stopped
    env_file: .env
    volumes:
      - postgres-data:/var/lib/postgresql
    networks: [gatus-internal]

  gatus:
    image: ghcr.io/twin/gatus:stable
    container_name: gatus
    restart: unless-stopped
    depends_on: [postgres]
    env_file: .env
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      GATUS_CONFIG_PATH: /config/config.yaml
    volumes:
      - ./config:/config:ro
    networks: [gatus-internal]

volumes:
  postgres-data:

networks:
  gatus-internal:

Altere também o trecho storage de config/config.yaml. Se a senha tiver caracteres reservados em URL, ela precisa ser codificada para uso na URL de conexão.

storage:
  type: postgres
  path: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable"
  caching: true

O sslmode=disable é apropriado apenas para essa rede Docker interna. Para PostgreSQL fora do host ou gerenciado, exija TLS e use a URL de conexão fornecida pelo serviço.

Inicie e valide

cd /opt/gatus
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs --tail=100
curl -I http://127.0.0.1:8080

O curl confirma que o serviço está escutando localmente. Para abrir o painel sem expor a porta, crie um túnel SSH a partir da sua máquina:

ssh -L 8080:127.0.0.1:8080 usuario@seu-servidor

Depois acesse http://localhost:8080 no navegador local. Não abra 8080 no firewall só para facilitar: quando você decidir disponibilizar uma status page ou administração, publique-a atrás de HTTPS, autenticação e um proxy reverso configurado para o seu ambiente.

Publique o painel com Nginx

O Compose mantém o Gatus em 127.0.0.1:8080. Para acessá-lo por um domínio, coloque Nginx na frente e use HTTPS. Em /etc/nginx/sites-available/gatus, adapte domínio e caminhos do certificado:

server {
    listen 80;
    server_name status.exemplo.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name status.exemplo.com;

    ssl_certificate /etc/letsencrypt/live/status.exemplo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/status.exemplo.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}
sudo ln -s /etc/nginx/sites-available/gatus /etc/nginx/sites-enabled/gatus
sudo nginx -t
sudo systemctl reload nginx

Emita o certificado antes de ativar o bloco HTTPS e não exponha o dashboard administrativo sem proteção. O Gatus oferece Basic Auth e OIDC na própria configuração; use uma delas quando a página não for pública. Para a implementação de Nginx no Ubuntu, consulte também nosso guia de Nginx e várias versões de PHP.

Gatus e IA: um uso prático, sem hype

O Gatus não é uma ferramenta de IA e não “conserta” código gerado por IA. A utilidade aqui é outra: mudanças ficam mais frequentes quando equipes usam assistência de IA, e uma sonda sintética pode verificar o caminho crítico após o deploy. Além de testar 200, valide um campo JSON, uma resposta esperada ou um limite de tempo. O próprio projeto discute esse papel de prevenção no contexto de mudanças aceleradas por IA.

Não transforme uma sonda em ação destrutiva. Se criar checks que fazem POST para testar um fluxo, a operação precisa ser idempotente, isolada e não pode alterar dados reais de produção. O YAML é um contrato operacional: revise-o como revisaria código.

O que fica para o próximo passo

Depois que o primeiro endpoint estiver saudável, avance pouco a pouco: adicione DNS ou TCP, configure alertas, use uma página pública separada e leve o YAML ao Git. Antes de guardar tokens de webhook ou senhas em configuração, retire-os do repositório e use o mecanismo de segredos adotado pela sua equipe.

Para detalhes completos de condições, alertas, armazenamento e segurança, consulte a documentação do Gatus e o repositório oficial. Acompanhe também as releases antes de atualizar a imagem. Com um arquivo curto e um check bem pensado, o Gatus já impede que o usuário seja o seu primeiro monitor.

Leitura relacionada: How Gatus Can Help Prevent Disasters in the Era of AI, no blog oficial do projeto.