Se ainda não tem a certeza do que são o Prometheus e o Grafana, leia o nosso artigo sobre Prometheus vs Grafana. Se já sabe a diferença, veja aqui como executá-los em conjunto.
Este artigo é a parte prática. Instala o Prometheus, o Grafana e o Node Exporter num único VPS com Docker Compose, coloca HTTPS à frente do Grafana com o Caddy, importa o painel Node Exporter Full (ID 1860) e mostra como recolher métricas de um segundo VPS através de WireGuard.
O teste original de abril de 2026 correu em Ubuntu 24.04 LTS com Docker Engine 27.x e Docker Compose v2.30. As versões fixadas na configuração abaixo foram entretanto atualizadas para as versões atualmente suportadas. Nesse teste original com cinco hosts, o hub usava cerca de 300 MB de RAM em repouso e entre 530 e 650 MB durante a recolha contínua.
TL;DR
- O VPS hub corre o Prometheus, o Grafana e o Node Exporter numa única stack de Compose, com o Caddy instalado no host como proxy inverso.
- O Prometheus e o Grafana escutam apenas em 127.0.0.1. O acesso público passa pelo Caddy com HTTPS automático.
- Adicione mais servidores instalando o Node Exporter em cada um e acrescentando entradas a
prometheus.yml. - O WireGuard é o caminho de rede recomendado entre o hub e os nós. A rede privada funciona bem quando os seus servidores já partilham uma rede privada.
- Um VPS de 2 GB chegou para o teste com cinco hosts abaixo, mas encare isso como referência e não como regra fixa por número de hosts.
O que vai construir
Eis, em traços gerais, o aspeto que a instalação terá quando terminar.
+-------------------+
| Your laptop |
+---------+---------+
| HTTPS
v
+--------------------------+----------------------------+
| MONITORING HUB VPS (2 GB RAM starting point) |
| Caddy (reverse proxy, auto HTTPS) |
| Grafana (port 3000, only via Caddy) |
| Prometheus (port 9090, internal only) |
| Node Exporter (port 9100, scraped on localhost) |
+----+---------------------------------+----------------+
| |
| scrape over WireGuard | scrape over WG
v v
+----+--------+ +-----+-------+
| App VPS 1 | | App VPS 2 |
| Node Expo. | | Node Expo. |
+-------------+ +-------------+
Um único VPS hub aloja toda a stack de monitorização. Cada um dos outros VPS que quiser vigiar corre apenas o Node Exporter. O Prometheus no hub recolhe as métricas de cada um, o Grafana visualiza-as e o Caddy trata do HTTPS.
O que você precisa
Para esta configuração em concreto, precisa de um VPS com Ubuntu para o hub, um domínio e acesso sudo.
- Um VPS com pelo menos 2 GB de RAM a correr Ubuntu 24.04 LTS.
- Um nome de domínio com um registo A a apontar para o IP público do VPS (por exemplo, grafana.example.com). É necessário para o HTTPS.
- Acesso root ou sudo por SSH.
Ao longo deste guia, substitua grafana.example.com pelo subdomínio que realmente apontou para o seu VPS de monitorização. Use o mesmo domínio na variável de ambiente do Grafana, na verificação de DNS e no Caddyfile.
Se só quiser monitorizar um servidor e ainda não precisar de HTTPS, pode correr a stack de Compose no VPS que já tem, sem a secção do proxy inverso. O resto do guia mantém-se válido.
Lance um VPS Ubuntu instantaneamente com acesso root e armazenamento NVMe.
Implantar VPS UbuntuPasso 1: preparação do servidor
Ligue-se por SSH ao VPS hub com um utilizador com sudo. Comece por atualizar o sistema.
sudo apt update && sudo apt upgrade -y
Instale o Docker Engine e o plugin do Compose a partir do repositório oficial do Docker.
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verifique se ambos estão instalados.
docker --version
docker compose version
Ambos os comandos devem devolver uma versão sem erros. As versões exatas do Docker Engine e do Compose dependem do que o repositório oficial disponibiliza quando os instalar.
sudo usermod -aG docker $USER
Termine a sessão e volte a entrar antes de continuar, para que a nova pertença ao grupo tenha efeito. O grupo docker concede na prática privilégios de root, por isso adicione apenas administradores de confiança.
Configure o UFW para permitir SSH, HTTP e HTTPS no hub de monitorização. A porta 80 trata do redirecionamento de HTTP para HTTPS e da validação ACME. O Grafana em si continua atrás do Caddy.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
Não abra as portas 3000, 9090 ou 9100 à internet pública. Os serviços de monitorização escutam em 127.0.0.1 por uma razão.
Passo 2: a stack de Compose
Crie um diretório para a stack e a configuração do Prometheus.
mkdir -p ~/monitoring/prometheus
cd ~/monitoring
Escreva o ficheiro de Compose.
# ~/monitoring/docker-compose.yml
services:
prometheus:
image: prom/prometheus:v3.13.2
container_name: prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
- '--web.enable-lifecycle'
- '--web.listen-address=127.0.0.1:9090'
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
network_mode: host
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
network_mode: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=127.0.0.1:9100'
- '--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($$|/)'
volumes:
- '/:/host:ro,rslave'
grafana:
image: grafana/grafana:13.1.3
container_name: grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://grafana.example.com
- GF_SERVER_HTTP_ADDR=127.0.0.1
volumes:
- grafana_data:/var/lib/grafana
network_mode: host
depends_on:
- prometheus
volumes:
prometheus_data:
grafana_data:
Agora escreva a configuração do Prometheus.
# ~/monitoring/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'monitoring-hub'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['127.0.0.1:9090']
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
Crie um ficheiro .env com a palavra-passe de administrador do Grafana. Use uma palavra-passe forte e não faça commit deste ficheiro no git.
cat > ~/monitoring/.env <<'EOF'
GRAFANA_ADMIN_PASSWORD='replace-with-a-strong-password'
EOF
chmod 600 ~/monitoring/.env
Algumas das opções acima merecem uma frase de explicação.
--web.listen-address=127.0.0.1:9090faz o Prometheus escutar apenas na interface de loopback do host. Assim a porta 9090 fica fora da rede pública, mas continua acessível ao Grafana e à administração local.--web.enable-lifecycleativaPOST /-/reload, para que possa aplicar alterações à configuração do Prometheus sem reiniciar o contentor.pid: host,network_mode: host, o bind mount da raiz do host e--path.rootfs=/hostdão ao Node Exporter em contentor o contexto do host de que precisa, em vez de monitorizar apenas o seu próprio ambiente de contentor.GF_USERS_ALLOW_SIGN_UP=falseimpede que os visitantes criem as suas próprias contas no Grafana. Isso não torna o Grafana privado: a página de início de sessão continua acessível publicamente através do Caddy.
Dica profissional: Se preferir saltar a instalação manual, a Cloudzy tem implementações com um clique de Grafana e Prometheus . A implementação do Prometheus também pode instalar o Node Exporter.
Passo 3: primeiro arranque e verificação
Arranque a stack.
cd ~/monitoring
docker compose up -d
Espere alguns segundos e verifique se os três contentores estão a correr.
docker compose ps
Os três serviços devem aparecer em estado running.
Abra um túnel SSH a partir do seu portátil para verificar a página de targets do Prometheus.
ssh -L 9090:localhost:9090 your-user@your-vps-ip
Depois abra http://localhost:9090/targets no navegador. Deverá ver dois targets, ambos em estado UP:
prometheus UP http://127.0.0.1:9090/metrics
node UP http://127.0.0.1:9100/metrics
Se algum estiver DOWN, avance para a secção Problemas comuns. Não continue enquanto ambos não estiverem UP.
Feche o túnel quando acabar de verificar os targets. De fora do VPS, o Prometheus continuará acessível apenas por este túnel SSH. O passo seguinte expõe o Grafana através de HTTPS.
Passo 4: proxy inverso com HTTPS usando o Caddy
O Caddy é um único binário e trata do HTTPS automaticamente. Para um proxy inverso de um só site, a configuração é mais curta do que o bloco equivalente do Nginx.
Instale o Caddy a partir do repositório oficial.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
Antes do passo seguinte, confirme que o registo DNS A de grafana.example.com aponta para o IP público do VPS. Sem isso, a validação ACME falha.
dig +short grafana.example.com
# Should print the VPS public IP
Edite o Caddyfile.
# /etc/caddy/Caddyfile
grafana.example.com {
reverse_proxy 127.0.0.1:3000
encode gzip
}
Recarregue o Caddy.
sudo systemctl reload caddy
O Caddy obtém e renova automaticamente certificados TLS publicamente fiáveis através de ACME, assim que o domínio aponte para o seu servidor e as portas 80 e 443 estejam acessíveis. Abra https://grafana.example.com no navegador: deverá ver a página de início de sessão do Grafana numa ligação HTTPS válida. Entre com admin e a palavra-passe do seu ficheiro .env.
Passo 5: adicionar o Prometheus como fonte de dados e importar o painel 1860
Na interface do Grafana, vá a Conexões > Fontes de dados > Adicionar fonte de dados e escolha Prometheus.
Defina o URL para:
http://127.0.0.1:9090
Nesta configuração, o Grafana e o Prometheus partilham a rede do host, enquanto o Prometheus escuta apenas em loopback. Clique em Save & test e confirme que o Grafana consegue consultar a API do Prometheus. Deverá ver "Successfully queried the Prometheus API".
Agora importe o painel. O Node Exporter Full (ID 1860, de rfmoz) é um painel comunitário muito usado para as métricas do Node Exporter. Cobre CPU, memória, E/S de disco, rede, descritores de ficheiros e temperaturas do hardware quando o host as expõe. Tem também variáveis para job e instance, por isso funciona em hub-and-spoke sem qualquer alteração.
Ir para Painéis > Novo > Importar painel, introduza o ID de painel 1860, selecione a sua fonte de dados Prometheus e importe-o.
O painel deverá preencher-se assim que o seu target do Node Exporter estiver UP. O painel 1860 usa também métricas dos coletores opcionais systemd e processes em alguns gráficos, por isso um gráfico vazio não significa necessariamente que o target esteja avariado.
Passo 6: adicionar um segundo VPS (hub-and-spoke)
Antes de arrancar o Node Exporter, certifique-se de que o IP privado ao qual pretende ligá-lo já existe no segundo VPS. Se estiver a usar WireGuard, conclua primeiro a sua configuração.
No segundo VPS, instale o Docker seguindo a parte de instalação do Docker do passo 1, mas não abra as portas 80 ou 443 só por causa da monitorização. Depois execute apenas o Node Exporter.
mkdir -p ~/node-exporter
cd ~/node-exporter
cat > docker-compose.yml <<'EOF'
services:
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=10.10.0.2:9100' # bind to the private monitoring IP, never 0.0.0.0
volumes:
- '/:/host:ro,rslave'
network_mode: host
EOF
docker compose up -d
Substitua 10.10.0.2 pelo IP privado de monitorização deste servidor. Se usar WireGuard, use o respetivo IP de WireGuard; se usar a rede privada da Cloudzy, use o IP da interface privada do VPS. Se o UFW já estiver ativo neste VPS, permita que apenas o hub de monitorização alcance o Node Exporter. Por exemplo, se o IP privado do hub for 10.10.0.1:
sudo ufw allow proto tcp from 10.10.0.1 to any port 9100
sudo ufw status
Substitua 10.10.0.1 pelo IP privado real do hub. Se o UFW estiver inativo, a opção explícita --web.listen-address continua a manter o Node Exporter fora da interface pública, mas outras máquinas com acesso a essa rede privada também podem alcançar a porta 9100.
Duas boas opções para o caminho de rede entre o hub e os nós:
- Rede WireGuard. Cada VPS junta-se a uma rede WireGuard e o Prometheus recolhe métricas de IPs privados. É a opção mais segura depois da configuração inicial do WireGuard. Oferecemos WireGuard como implementação com um clique e temos também um tutorial de configuração já existente sobre ele.
- Rede privada da Cloudzy. As instâncias VPS da Cloudzy na mesma região recebem uma interface privada para tráfego este-oeste, por isso pode recolher métricas desse endereço em vez de montar um túnel WireGuard à parte.
Assim que o Node Exporter estiver a correr no segundo VPS e acessível no seu IP privado, substitua o job node existente em prometheus.yml no hub pelo bloco abaixo.
# Update the existing 'node' job in ~/monitoring/prometheus/prometheus.yml
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
- targets: ['10.10.0.2:9100']
labels:
host: 'app-vps-1'
tier: 'production'
Recarregue o Prometheus sem reiniciar o contentor.
curl -X POST http://localhost:9090/-/reload
Volte a abrir o túnel SSH do passo 3 e aceda a http://localhost:9090/targets. O novo target deverá aparecer como UP. Abra o painel Node Exporter Full, mude a variável instance no topo para o novo servidor e verá os respetivos gráficos.
Consumo de recursos e quando fazer upgrade
Estes números vêm do teste original de abril de 2026, num VPS Ubuntu de 2 GB com cinco hosts monitorizados. Encare-os como referência para esta carga de trabalho e não como garantia de dimensionamento para versões mais recentes.
| Componente | RAM em repouso | RAM em atividade (1 host) | RAM com 5 hosts | Disco (retenção de 15 d, 5 hosts) |
|---|---|---|---|---|
| Prometheus | ~100 MB | ~150 MB | ~250-350 MB | ~500 MB a 1,5 GB |
| Grafana | ~150 MB | ~180 MB | ~200 MB | ~50 MB |
| Node Exporter | ~15 MB | ~20 MB | não aplicável | insignificante |
| Caddy | ~30 MB | ~40 MB | ~40 MB | não aplicável |
| Total do hub | ~300 MB | ~390 MB | ~530-650 MB | ~1,5 GB de conjunto de trabalho |
Faça upgrade quando o hub começar a ficar sem memória ou sem folga de disco. O número de hosts, por si só, é um mau critério de dimensionamento, porque a cardinalidade das séries, os coletores ativados, o intervalo de recolha e a retenção alteram todos o consumo. Para armazenamento centralizado a longo prazo, o Prometheus suporta integrações de armazenamento remoto. O VictoriaMetrics é uma das opções compatíveis com o Prometheus.
Problemas comuns
Os sete problemas que surgem com mais frequência, com as respetivas soluções.
- O Prometheus está acessível a partir da internet pública. Um simples mapeamento de porta 9090:9090 expõe o Prometheus ao mundo inteiro. Solução: mantenha
--web.listen-address=127.0.0.1:9090no comando do Prometheus, como mostrado acima. Assim o Prometheus escuta apenas na interface de loopback do host. - A fonte de dados do Grafana não consegue chegar ao Prometheus. Esta stack usa a rede do host, por isso o Grafana chega ao Prometheus em http://127.0.0.1:9090. Verifique se o Prometheus está a correr e continua a escutar em loopback.
- O painel do Node Exporter mostra "No data". Três causas habituais. (a) O Prometheus não está a recolher o target. Verifique
/targets. (b) A etiqueta job na variável do painel não corresponde aojob_namena configuração de scrape. (c) Uma firewall bloqueia a porta 9100 entre o hub e o target. - A palavra-passe de administrador do Grafana continua
admin/adminem produção. DefinirGF_SECURITY_ADMIN_PASSWORDa partir de um ficheiro .env antes do primeiro arranque. Se se esqueceu, mude-a no primeiro início de sessão e desative o registo. - O Caddy dá "ACME challenge failed". O registo DNS A ainda não propagou, ou a porta 80 está bloqueada. Execute
ufw allow 80,443/tcp, espere pelo DNS e executesudo systemctl reload caddy. Usedig +shortpara confirmar a propagação. - O disco do Prometheus enche. Etiquetas de cardinalidade elevada ou intervalos de recolha curtos com muitos hosts podem encher o volume depressa. Vigie
prometheus_tsdb_head_seriese o tamanho do volume. Mitigações: desative os coletores do Node Exporter que não usa, aumente oscrape_intervalpara 30s ou reduza a retenção. - Erros de permissões nos bind mounts. Se montar um diretório do host em vez de um volume nomeado, o UID do contentor (65534 para o Prometheus, 472 para o Grafana) precisa de permissão de escrita. Os volumes nomeados, como no ficheiro de Compose acima, evitam isto.
Quando esta stack é exagero
Se tudo o que quer é um alerta quando um URL deixa de responder, esta stack é exagero. Uptime Kuma é uma opção bem mais leve se só precisar de verificações básicas de disponibilidade.
Perguntas frequentes
Qual é a diferença entre o Prometheus e o Grafana?
O Prometheus é uma base de dados de séries temporais: recolhe métricas dos targets configurados no intervalo que definir, guarda-as em disco e responde a consultas PromQL. O Grafana é uma camada de visualização que se liga ao Prometheus (e a muitas outras fontes de dados) e desenha painéis. Quase sempre vai querer os dois: o Prometheus para recolher e guardar, o Grafana para mostrar.
De quanta RAM precisa uma instalação de Prometheus + Grafana?
Um hub de monitorização a correr o Prometheus, o Grafana, o Node Exporter e um proxy inverso num único VPS usa cerca de 300 MB de RAM em repouso e entre 530 e 650 MB quando recolhe ativamente de cinco hosts a cada 15 segundos.
Posso monitorizar vários servidores com uma só instância do Grafana?
Sim. O padrão habitual é hub-and-spoke. Uma única instância do Prometheus num VPS hub recolhe do Node Exporter que corre em cada um dos outros servidores que quer vigiar. O Grafana no hub consulta apenas esse Prometheus. O painel Node Exporter Full (ID 1860) suporta uma variável instance, por isso alterna entre servidores a partir de um só painel.
Qual é o melhor painel do Grafana para o Node Exporter?
Para esta configuração, o Node Exporter Full (painel com o ID 1860, de rfmoz) é uma excelente escolha por omissão. Cobre as principais métricas de host do Node Exporter e suporta as variáveis job e instance para monitorizar vários servidores. Alguns gráficos dependem de coletores opcionais do Node Exporter, por isso um gráfico vazio não significa necessariamente que o target de recolha esteja avariado.
Como exponho o Grafana através de HTTPS?
Execute o Grafana ligado a 127.0.0.1:3000 e coloque à frente um proxy inverso que trate do HTTPS. O Caddy é a opção mais simples: um Caddyfile de quatro linhas com reverse_proxy 127.0.0.1:3000 e um bloco de domínio trata de tudo, incluindo a gestão automática dos certificados TLS.
O Prometheus + Grafana são gratuitos para uso comercial?
O Prometheus é licenciado sob a Apache 2.0. O Grafana OSS está sob AGPLv3. O uso interno e comercial do Grafana OSS não modificado é permitido, mas modificá-lo ou distribuí-lo, ou disponibilizar uma versão modificada através de uma rede, pode criar obrigações de partilha do código-fonte ao abrigo da AGPL. O Grafana Enterprise e o Grafana Cloud têm termos comerciais próprios.
Quando devo mudar do Prometheus para o VictoriaMetrics?
Considere o VictoriaMetrics quando uma retenção mais longa, uma cardinalidade de séries elevada ou várias instâncias do Prometheus tornarem mais difícil operar a TSDB local do Prometheus dentro do orçamento de memória e disco do seu servidor. O VictoriaMetrics consegue receber dados do Prometheus e expor uma API de consulta compatível, por isso pode servir de armazenamento de longo prazo ou de backend de métricas para o Grafana. Teste-o com a sua própria carga de trabalho em vez de mudar a partir de um limiar fixo de RAM.
