#!/bin/bash ############################################################# #### Grafana Tempo Install Script for Oracle Linux, #### #### Centos/Redhat and Debian/Ubuntu Servers. #### #### #### #### Author: Phil Connor #### #### Contact: contact@mylinux.work #### #### License: MIT #### #### Version 1.00 #### #### #### #### To use this script chmod it to 755 #### #### or simply type bash #### ############################################################# ######################## ### System Variables ### ######################## if [ "$(command -v lsb_release)" ]; then OS=$(lsb_release -i | awk '{print $3}' | tr '[:upper:]' '[:lower:]') else OS=$(grep PRETTY_NAME /etc/os-release | sed 's/PRETTY_NAME=//g' | tr -d '="' | awk '{print $1}' | tr '[:upper:]' '[:lower:]') fi domain=mylinux.work bindir=/usr/local/bin tempodir=/etc/tempo datadir=/tempo if [ -d "/usr/lib/systemd/system" ]; then psdir='/etc/systemd/system' else psdir='/usr/lib/systemd/system' fi ######################### ### Check permissions ### ######################### if [[ $EUID -ne 0 ]]; then echo '' echo "$(basename "$0") This script must be run as root! Login as root, or sudo/su." echo '' exit 1 fi ###################### ### Package Manager ## ###################### pkgmgr="yum -y" if [ "$OS" = "ubuntu" ]; then pkgmgr="apt -y" fi ################################# #### Add Tempo User/Group #### ################################# if ! grep tempo /etc/passwd; then groupadd --system tempo if [ "$OS" = "ubuntu" ]; then useradd -s /sbin/nologin --system -g tempo tempo else useradd -m -s /bin/false tempo -g tempo fi fi ################################# #### Check for wget and curl #### ################################# if [ ! "$(command -v wget)" ]; then $pkgmgr install wget fi if [ ! "$(command -v curl)" ]; then $pkgmgr install curl fi if [ ! "$(command -v unzip)" ]; then $pkgmgr install unzip fi ########################## ### Install Tempo ### ########################## install_tempo() { { # Create base directories if they don't exist if [ ! -d "$tempodir" ]; then mkdir -p $tempodir || { echo "Failed to create $tempodir directory"; exit 1; } fi if [ ! -d "$datadir" ]; then mkdir -p $datadir || { echo "Failed to create $datadir directory"; exit 1; } fi # Create Tempo subdirectories mkdir -p $datadir/{traces,wal,generator/wal} chown -R tempo:tempo $datadir # Download and install Tempo cd /tmp || exit 2 echo "Downloading latest Grafana Tempo..." curl -s https://api.github.com/repos/grafana/tempo/releases/latest | grep browser_download_url | grep linux_amd64.tar.gz | cut -d '"' -f 4 | wget -qi - || { echo "Failed to download Tempo"; exit 1; } tar -xvf tempo_*_linux_amd64.tar.gz mv tempo $bindir/tempo || exit 1 chown tempo:tempo $bindir/tempo || exit 1 rm -rf /tmp/tempo_*_linux_amd64.tar.gz # Create Tempo config touch $tempodir/tempo.yml { echo '# Tempo Configuration - Single Instance Mode' echo 'stream_over_http_enabled: true' echo '' echo 'server:' echo ' http_listen_port: 3200' echo ' grpc_listen_port: 9095' echo ' log_level: info' echo '' echo 'distributor:' echo ' receivers:' echo ' otlp:' echo ' protocols:' echo ' grpc:' echo ' endpoint: 0.0.0.0:4317' echo ' http:' echo ' endpoint: 0.0.0.0:4318' echo '' echo 'ingester:' echo ' max_block_duration: 5m' echo '' echo 'compactor:' echo ' compaction:' echo ' block_retention: 720h' echo '' echo 'metrics_generator:' echo ' registry:' echo ' external_labels:' echo ' source: tempo' echo ' storage:' echo " path: $datadir/generator/wal" echo ' remote_write:' echo ' - url: http://localhost:9009/api/v1/push' echo '' echo 'storage:' echo ' trace:' echo ' backend: local' echo ' local:' echo " path: $datadir/traces" echo ' wal:' echo " path: $datadir/wal" echo '' echo 'overrides:' echo ' defaults:' echo ' metrics_generator:' echo ' processors:' echo ' - service-graphs' echo ' - span-metrics' echo ' - local-blocks' } > $tempodir/tempo.yml chown tempo:tempo $tempodir/tempo.yml # Create systemd service { echo '[Unit]' echo 'Description=Grafana Tempo' echo 'Documentation=https://grafana.com/docs/tempo/' echo 'After=network-online.target' echo 'Wants=network-online.target' echo '' echo '[Service]' echo 'Type=simple' echo 'User=tempo' echo 'Group=tempo' echo "ExecStart=$bindir/tempo -config.file=$tempodir/tempo.yml" echo "ExecReload=/bin/kill -HUP \$MAINPID" echo 'TimeoutStopSec=20s' echo 'SendSIGKILL=no' echo '' echo '# Output to journal' echo 'StandardOutput=journal' echo 'StandardError=journal' echo 'SyslogIdentifier=tempo' echo '' echo '# Restart' echo 'Restart=on-failure' echo 'RestartSec=5s' echo '' echo '# Security' echo 'NoNewPrivileges=yes' echo 'PrivateTmp=yes' echo 'ProtectSystem=full' echo 'ProtectHome=yes' echo "ReadWritePaths=$datadir" echo '' echo '# Resource limits' echo 'LimitNOFILE=1048576' echo 'LimitNPROC=1048576' echo '' echo '# Environment' echo 'Environment=GOMAXPROCS=4' echo '' echo '[Install]' echo 'WantedBy=multi-user.target' } > $psdir/tempo.service systemctl daemon-reload systemctl enable --now tempo echo "" echo "==========================================" echo "Tempo installation complete!" echo "==========================================" echo "Tempo UI: http://localhost:3200" echo "Config: $tempodir/tempo.yml" echo "Data: $datadir" echo "OTLP gRPC: localhost:4317" echo "OTLP HTTP: localhost:4318" echo "" } } ################################ ### Install and Config Nginx ### ################################ install_nginx() { { $pkgmgr install nginx if [ -d "/etc/nginx/sites-available" ]; then sitesa=/etc/nginx/sites-available sitese=/etc/nginx/sites-enabled/ elif [ -d "/etc/nginx/conf.d" ]; then sitesa=/etc/nginx/conf.d fi touch "$sitesa"/tempo.conf { echo 'server {' echo ' listen 80;' echo ' listen [::]:80;' echo '' echo " server_name tempo.$domain;" echo '' echo ' location / {' echo ' proxy_pass http://localhost:3200/;' # shellcheck disable=SC2016 echo ' proxy_set_header Host $host;' # shellcheck disable=SC2016 echo ' proxy_set_header X-Real-IP $remote_addr;' # shellcheck disable=SC2016 echo ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' # shellcheck disable=SC2016 echo ' proxy_set_header X-Forwarded-Proto $scheme;' echo ' proxy_read_timeout 300s;' echo ' proxy_connect_timeout 75s;' echo ' }' echo '}' } > "$sitesa"/tempo.conf if [ -d "/etc/nginx/sites-available" ]; then ln -s "$sitesa"/tempo.conf "$sitese" 2>/dev/null || true fi if nginx -t; then systemctl restart nginx echo "Nginx configured for Tempo at tempo.$domain" else echo "Nginx configuration test failed" fi } } ###################### ### Function Calls ### ###################### install_tempo # Uncomment to install nginx reverse proxy # install_nginx ############################################################# echo "" echo "==========================================" echo "Installation Summary" echo "==========================================" echo "Tempo version: $(tempo --version 2>&1 | head -1)" echo "Status: $(systemctl is-active tempo)" echo "" echo "Check status: systemctl status tempo" echo "View logs: journalctl -u tempo -f" echo ""