Skip to main content

🛠️ Prerequisites

Before installing anything, verify your system meets the requirements and that the necessary ports are free. Skipping this step causes the most common installation failures.


📚 Concepts to Understand First

What Is a Scrape Target?

Prometheus collects metrics by visiting a URL like http://your-app:3001/metrics on a schedule. This URL must exist and return data in Prometheus format. This is called a "scrape target."

What Is a Label?

A label is a key-value tag attached to data. For example:

{app="healthtune", level="error", host="gcp-vm-1"}

Labels let you filter and group your data in Grafana queries.

What Is a Docker Volume?

A folder inside Docker that persists data even when containers restart or are deleted. Without volumes, all your metrics/logs/traces would vanish every time you run docker compose down.


💻 System Requirements

Minimum (Dev / Testing)

ResourceMinimum
CPU2 vCPU
RAM4 GB
Disk20 GB free
OSUbuntu 20.04+ / Debian 11+ / Any Linux
ResourceRecommended
CPU4+ vCPU
RAM8+ GB
Disk50+ GB (metrics + logs grow fast)
OSUbuntu 22.04 LTS

💡 The Grafana stack is more RAM-efficient than ELK but Prometheus TSDB and Loki can grow. Set up data retention policies early (covered in Future Improvements).


🔌 Check If Required Ports Are Free

This is the most important pre-install step. Two services cannot share the same port.

Linux / Ubuntu

Check all stack ports at once:

sudo ss -ltnp | egrep ':(3000|9090|3100|3200|4317|4318|9100|9080)\b' || echo "All ports free"

Check individual ports:

sudo ss -ltnp | grep ':3000' # Grafana
sudo ss -ltnp | grep ':9090' # Prometheus
sudo ss -ltnp | grep ':3100' # Loki
sudo ss -ltnp | grep ':3200' # Tempo
sudo ss -ltnp | grep ':4317' # OTEL gRPC
sudo ss -ltnp | grep ':4318' # OTEL HTTP
sudo ss -ltnp | grep ':9100' # Node Exporter

🟢 No output = port is free — good, proceed 🔴 Output appears = port is in use — note which service owns it

Find out what's using a specific port:

sudo ss -ltnp | grep ':3000'
# Output shows the process name and PID
# Example: users:(("grafana",pid=1234,fd=6))

Windows (PowerShell — run as Administrator)

$ports = @(3000, 9090, 3100, 3200, 4317, 4318, 9100, 9080)
foreach ($port in $ports) {
$result = netstat -ano | Select-String ":$port\s"
if ($result) {
Write-Host "Port $port IN USE:" -ForegroundColor Red
Write-Host $result
} else {
Write-Host "Port $port FREE" -ForegroundColor Green
}
}

Find which app owns a port (get the PID first from above, then):

# Replace 1234 with actual PID from netstat output
Get-Process -Id 1234 | Select-Object Name, Id

macOS

for port in 3000 9090 3100 3200 4317 4318 9100 9080; do
result=$(lsof -i :$port 2>/dev/null)
if [ -n "$result" ]; then
echo "Port $port IN USE: $result"
else
echo "Port $port FREE"
fi
done

🔧 Resolving Port Conflicts

If a port is already taken, you have two options:

Option 1 — Change the conflicting service's port (if it's one of your own services)

Option 2 — Change the stack tool's host port in docker-compose.yaml

Port mapping format in Docker Compose is always HOST_PORT:CONTAINER_PORT. The left side (host) is what you change. The right side (container) stays the same.

Example — if port 3000 is already used by another app, change Grafana to 3001:

# In docker-compose.yaml, Grafana service:
ports:
- "3001:3000" # Changed host port from 3000 to 3001

Then access Grafana at http://localhost:3001 instead.


🐳 Install Docker

Ubuntu / Debian (Linux)

# Update packages
sudo apt update

# Install Docker
sudo apt install -y docker.io

# Enable and start Docker service
sudo systemctl enable docker
sudo systemctl start docker

# Add your user to docker group (avoid sudo every time)
sudo usermod -aG docker $USER

# Apply the group change in current terminal session
newgrp docker

# Verify
docker --version
docker run hello-world

Ubuntu — Install Docker Engine (Official method, newer)

# Remove old versions if any
sudo apt remove docker docker-engine docker.io containerd runc

# Install prerequisites
sudo apt update
sudo apt install -y ca-certificates curl gnupg

# 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

# Add repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker Engine + Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Verify
docker --version
docker compose version

Windows

  1. Download Docker Desktop from docker.com/products/docker-desktop
  2. Run the installer — it installs both Docker and Docker Compose
  3. Start Docker Desktop from the Start Menu
  4. Open PowerShell and verify:
docker --version
docker compose version

💡 On Windows, Docker Desktop uses WSL2 (Windows Subsystem for Linux) under the hood. Make sure WSL2 is enabled — the Docker installer usually handles this.

macOS

# Using Homebrew
brew install --cask docker

# Start Docker Desktop from Applications
# Then verify:
docker --version
docker compose version

🐙 Verify Docker Compose

# New style (v2, built-in plugin)
docker compose version
# Expected: Docker Compose version v2.x.x

# Old style (v1, separate binary — still works)
docker-compose --version

Both work. This guide uses docker compose (no hyphen) which is the current standard.


📦 Install Git

Linux

sudo apt install -y git
git --version

Windows

Download from git-scm.com and install. Then verify in PowerShell:

git --version

macOS

# Git comes with Xcode command line tools
xcode-select --install
# Or via Homebrew:
brew install git

📋 Pre-Installation Checklist

Run through this entirely before starting the install:

# 1. Docker running?
docker --version && docker info | grep "Server Version"

# 2. Docker Compose available?
docker compose version

# 3. Git available?
git --version

# 4. Disk space available? (need at least 5 GB free for images)
df -h /

# 5. RAM available?
free -h

# 6. All ports free?
sudo ss -ltnp | egrep ':(3000|9090|3100|3200|4317|4318|9100)\b' || echo "All clear"

Everything checks out? Move on to Install Prometheus →