Grafana + Prometheus na VPS com Docker Compose

Grafana e Prometheus são o par padrão de observabilidade para infraestrutura moderna, Prometheus coleta e armazena métricas no formato de séries temporais; Grafana visualiza em dashboards e dispara alertas. Com Docker Compose, o stack completo sobe em um único comando e dashboards prontos da comunidade cobrem 90% das necessidades.

docker-compose.yml: stack completo

Prometheus + Grafana + Node Exporter em um único arquivo:

yaml
services:
  prometheus:
    image: prom/prometheus:latest
    restart: always
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'
      - '--storage.tsdb.path=/prometheus'
      - '--web.enable-lifecycle'       # permite reload via POST /-/reload
    ports:
      - "127.0.0.1:9090:9090"          # apenas loopback — acesse via tunel SSH
    networks:
      - monitoring

  grafana:
    image: grafana/grafana-oss:latest
    restart: always
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-changeme}
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_SERVER_ROOT_URL: https://grafana.seudominio.com.br
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "127.0.0.1:3000:3000"          # apenas loopback
    networks:
      - monitoring

  node_exporter:
    image: prom/node-exporter:latest
    restart: always
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--path.rootfs=/rootfs'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)'
    ports:
      - "127.0.0.1:9100:9100"
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:

networks:
  monitoring:

prometheus.yml: configuração de scrape

Prometheus coleta métricas dos targets em intervalos regulares:

yaml
# prometheus/prometheus.yml
global:
  scrape_interval: 15s          # coletar métricas a cada 15 segundos
  evaluation_interval: 15s      # avaliar regras a cada 15 segundos

scrape_configs:
  # Prometheus se auto-monitora
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Node Exporter — métricas do sistema operacional
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['node_exporter:9100']
        labels:
          instance: 'vps-prod-01'
          env: 'production'

  # Aplicação Node.js (se expuser /metrics)
  - job_name: 'minha_api'
    static_configs:
      - targets: ['app:3000']
    metrics_path: '/metrics'

  # cAdvisor — métricas de containers Docker
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

Configurar Grafana: datasource e primeiro dashboard

Após subir o stack, configure Grafana para usar Prometheus como fonte de dados:

bash
# 1. Acesse http://localhost:3000 (via tunel SSH)
#    Login padrão: admin / changeme (ou o GRAFANA_PASSWORD definido)

# 2. Adicionar datasource via API (automatizável):
curl -X POST http://localhost:3000/api/datasources \
  -H "Content-Type: application/json" \
  -u admin:changeme \
  -d '{
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://prometheus:9090",
    "access": "proxy",
    "isDefault": true
  }'

# 3. Importar dashboard pronto da comunidade:
#    - ID 1860: Node Exporter Full (métricas completas do SO)
#    - ID 893:  Docker & System Monitoring
#    - ID 15172: Node Exporter for Prometheus Dashboard

# Via interface: Dashboards → Import → Digite o ID → Load → Select datasource

# 4. Verificar que Prometheus está recebendo métricas:
curl http://localhost:9090/api/v1/targets | python3 -m json.tool | grep '"health"'

Acesso seguro ao Grafana via Nginx

Para acesso web sem túnel SSH, proteja com Nginx e HTTPS:

nginx
# /etc/nginx/sites-available/grafana
server {
    listen 443 ssl;
    http2 on;
    server_name grafana.seudominio.com.br;

    ssl_certificate /etc/letsencrypt/live/grafana.seudominio.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grafana.seudominio.com.br/privkey.pem;

    # Autenticação básica como camada extra
    auth_basic "Grafana — acesso restrito";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# Criar usuário para autenticação básica
apt install apache2-utils
htpasswd -c /etc/nginx/.htpasswd admin

Queries PromQL essenciais para começar

PromQL é a linguagem de query do Prometheus. Estas queries cobrem os casos mais comuns:

promql
# CPU usage (%)
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Memória disponível (bytes)
node_memory_MemAvailable_bytes

# Uso de disco (%)
100 - ((node_filesystem_avail_bytes{mountpoint="/"} /
        node_filesystem_size_bytes{mountpoint="/"}) * 100)

# Taxa de requisições HTTP por segundo
rate(http_requests_total[5m])

# Load average (1 minuto)
node_load1

# Uptime do servidor
time() - node_boot_time_seconds

# Containers Docker rodando
engine_daemon_container_states_containers{state="running"}

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

Com retenção de 30 dias e 3-5 targets: Prometheus ~200-500 MB RAM + ~2-5 GB disco. Grafana ~100-200 MB RAM. Total: ~700 MB RAM. Para VPS de 2 GB, é viável junto com a aplicação. Para VPS de 1 GB: use Netdata (mais leve) ou Grafana Cloud (hosted, gratuito para uso básico).

Grafana OSS: self-hosted, gratuito, sem limites. Grafana Cloud: hosted pela Grafana Labs, plano free com 10k métricas, 50 GB logs e 50 GB traces, ideal para começar sem gerenciar infraestrutura. Para VPS de produção: OSS self-hosted dá mais controle. Para equipes pequenas sem ops: Cloud economiza tempo.

--storage.tsdb.retention.time=90d aumenta para 90 dias. O espaço em disco cresce proporcionalmente (~5 GB para 90 dias com 5 targets). Para retenção longa (1+ ano): use Thanos ou VictoriaMetrics como storage de longo prazo, com Prometheus enviando dados via remote_write.

Opção 1: adicione cada VPS como target no prometheus.yml com o IP correspondente. Cada VPS precisa ter Node Exporter rodando e acessível (abra a porta 9100 apenas para o IP do servidor Prometheus). Opção 2: Prometheus Federation, cada VPS tem seu Prometheus, um central agrega. Para 2-5 VPS: opção 1 é mais simples.

Prometheus: open source, pull-based, ótimo ecossistema, padrão de facto. InfluxDB: push-based, melhor para séries temporais de alta frequência, bom para IoT. Datadog: SaaS, tudo incluído, caro para uso intenso. Para VPS e infraestrutura cloud: Prometheus + Grafana é o stack padrão da indústria.