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:
    Dica
    Expor Prometheus e Grafana apenas no loopback (127.0.0.1) impede acesso externo. Acesse via túnel SSH: ssh -L 3000:localhost:3000 deploy@IP e abra http://localhost:3000. Para acesso web: coloque Nginx como proxy com autenticação.

    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"}

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes