#!/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 <}:3000 (first login admin/admin) OTLP ingress : ${IP:-}:4317 (gRPC) / ${IP:-}:4318 (HTTP) Alloy debug UI : http://${IP:-}:12345 Prometheus : http://${IP:-}:9090 Point apps at: OTEL_EXPORTER_OTLP_ENDPOINT=http://${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