Role of the application server
Runs your product traffic and exposes metrics:
- Node.js app (+
/metricslater) - Node Exporter (host CPU/RAM/disk)
- Nginx reverse proxy
- PM2 process manager
Users → Nginx :80 → Node.js app
↘ Node Exporter :9100 → Prometheus
EC2 basics
- Ubuntu LTS, open
22,80, and9100from the monitoring server (and80from users) - SSH in and update:
sudo apt update && sudo apt upgrade -y
Docker + Node Exporter
sudo apt install -y docker.io
sudo systemctl enable --now docker
docker run -d --name=node-exporter --restart unless-stopped \
-p 9100:9100 \
prom/node-exporter
curl http://localhost:9100/metrics | headExample metrics: node_cpu_seconds_total, node_memory_MemAvailable_bytes, node_filesystem_avail_bytes.
Node.js app + PM2
sudo apt install -y nodejs npm git
git clone <your-repo>
cd <project>
npm install
# set .env as required
sudo npm install -g pm2
pm2 start app.js --name api
pm2 status
pm2 logs
pm2 startup
pm2 savePM2 keeps the process up and restarts it after reboot.
Nginx reverse proxy
sudo apt install -y nginx# /etc/nginx/sites-available/app
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginxPoint Prometheus at this host
On the monitoring server, add a scrape job:
- job_name: "node"
static_configs:
- targets: ["<APP_PRIVATE_OR_PUBLIC_IP>:9100"]Reload Prometheus (/-/reload if enabled, or restart the container).
Prefer private IPs + security groups so Node Exporter is not open to the whole internet.