Files
2026-06-01 10:52:06 -05:00

123 lines
5.4 KiB
Bash

#!/usr/bin/env bash
#
# Provision the standalone BlueLaminate observability stack on a fresh Debian LXC:
# Grafana + Loki + Tempo + Alloy (Grafana apt repo, each with its own systemd unit)
# Prometheus (official release tarball -> /opt/prometheus + our unit)
#
# Idempotent: safe to re-run (re-applies configs and restarts services). Run as root.
#
# sudo ./install.sh
#
# Override the Prometheus version with PROM_VERSION=x.y.z ./install.sh if needed.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ "${EUID}" -ne 0 ]]; then
echo "ERROR: run as root (sudo ./install.sh)." >&2
exit 1
fi
ARCH="$(dpkg --print-architecture)" # amd64 / arm64
echo "==> Target architecture: ${ARCH}"
# --- prerequisites ------------------------------------------------------------------------
echo "==> Installing prerequisites"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y apt-transport-https software-properties-common gpg wget curl tar
# --- Grafana apt repo: grafana, loki, tempo, alloy ----------------------------------------
echo "==> Adding the Grafana apt repository"
mkdir -p /etc/apt/keyrings
if [[ ! -s /etc/apt/keyrings/grafana.asc ]]; then
wget -qO /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
fi
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" \
> /etc/apt/sources.list.d/grafana.list
apt-get update -y
echo "==> Installing Grafana, Loki, Tempo, Alloy"
apt-get install -y grafana loki tempo alloy
# --- Prometheus (release tarball) ---------------------------------------------------------
echo "==> Installing Prometheus"
PROM_VERSION="${PROM_VERSION:-$(curl -fsSL https://api.github.com/repos/prometheus/prometheus/releases/latest \
| grep -oP '"tag_name":\s*"v\K[^"]+' || true)}"
PROM_VERSION="${PROM_VERSION:-3.2.1}"
echo " Prometheus version: ${PROM_VERSION}"
id -u prometheus &>/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin prometheus
PROM_DIR="prometheus-${PROM_VERSION}.linux-${ARCH}"
TMP="$(mktemp -d)"
trap 'rm -rf "${TMP}"' EXIT
wget -qO "${TMP}/prom.tar.gz" \
"https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/${PROM_DIR}.tar.gz"
tar -xzf "${TMP}/prom.tar.gz" -C "${TMP}"
install -d /opt/prometheus
install -m 0755 "${TMP}/${PROM_DIR}/prometheus" /opt/prometheus/prometheus
install -m 0755 "${TMP}/${PROM_DIR}/promtool" /opt/prometheus/promtool
# --- data directories ---------------------------------------------------------------------
echo "==> Creating data directories"
install -d -o prometheus -g prometheus /var/lib/prometheus
install -d -o loki -g loki /var/lib/loki /var/lib/loki/chunks /var/lib/loki/rules /var/lib/loki/compactor
install -d -o tempo -g tempo /var/lib/tempo /var/lib/tempo/wal /var/lib/tempo/blocks \
/var/lib/tempo/generator/wal /var/lib/tempo/generator/traces
# --- configuration ------------------------------------------------------------------------
echo "==> Installing configuration files"
install -d /etc/alloy /etc/loki /etc/tempo /etc/prometheus
install -m 0644 "${SCRIPT_DIR}/alloy/config.alloy" /etc/alloy/config.alloy
install -m 0644 "${SCRIPT_DIR}/loki/loki.yml" /etc/loki/config.yml
install -m 0644 "${SCRIPT_DIR}/tempo/tempo.yml" /etc/tempo/config.yml
install -m 0644 "${SCRIPT_DIR}/prometheus/prometheus.yml" /etc/prometheus/prometheus.yml
install -m 0644 "${SCRIPT_DIR}/prometheus/prometheus.service" /etc/systemd/system/prometheus.service
# Point Alloy's systemd unit at our config (the package reads /etc/default/alloy).
cat > /etc/default/alloy <<'EOF'
CONFIG_FILE="/etc/alloy/config.alloy"
CUSTOM_ARGS=""
RESTART_ON_UPGRADE=true
EOF
# Grafana provisioning (datasources + dashboards).
echo "==> Installing Grafana provisioning"
install -d /etc/grafana/provisioning/datasources \
/etc/grafana/provisioning/dashboards \
/var/lib/grafana/dashboards
install -m 0644 "${SCRIPT_DIR}/grafana/datasources.yml" /etc/grafana/provisioning/datasources/bluelaminate.yml
install -m 0644 "${SCRIPT_DIR}/grafana/dashboards.yml" /etc/grafana/provisioning/dashboards/bluelaminate.yml
install -m 0644 "${SCRIPT_DIR}"/grafana/dashboards/*.json /var/lib/grafana/dashboards/
chown -R grafana:grafana /var/lib/grafana/dashboards 2>/dev/null || true
# --- start everything ---------------------------------------------------------------------
echo "==> Enabling + starting services"
systemctl daemon-reload
systemctl enable --now grafana-server loki tempo prometheus alloy
systemctl restart loki tempo prometheus alloy grafana-server
# --- summary ------------------------------------------------------------------------------
IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
cat <<EOF
============================================================================
BlueLaminate observability stack installed.
Grafana UI : http://${IP:-<lxc-ip>}:3000 (first login admin/admin)
OTLP ingress : ${IP:-<lxc-ip>}:4317 (gRPC) / ${IP:-<lxc-ip>}:4318 (HTTP)
Alloy debug UI : http://${IP:-<lxc-ip>}:12345
Prometheus : http://${IP:-<lxc-ip>}:9090
Point apps at: OTEL_EXPORTER_OTLP_ENDPOINT=http://${IP:-<lxc-ip>}:4318
Readiness checks:
systemctl is-active grafana-server loki tempo prometheus alloy
curl -s localhost:3100/ready # Loki
curl -s localhost:3200/ready # Tempo
curl -s localhost:9090/-/ready # Prometheus
============================================================================
EOF