#!/usr/bin/env bash # check-env.sh — Verify the deployment environment for Linear Void. # Mirrors scripts/check-env.ps1. # # Checks, against the target Docker host (default test lab 192.168.88.40): # 1. Docker Engine reachability over the TCP socket (port 2375). # 2. Coolify helper stack (proxy/Traefik, sentinel, cloudflared). # 3. Linear Void containers (playout, chat, nginx, redis, db, prometheus, grafana). # 4. Public endpoints (app, HLS manifest, admin). # 5. Health endpoints exposed by the services. # # Usage: # ./scripts/check-env.sh # ./scripts/check-env.sh -t 192.168.88.40 # ./scripts/check-env.sh -t 192.168.88.40 -p 2375 --only-containers # # Exit code is 0 when all required checks pass, 1 otherwise. set -uo pipefail TARGET=192.168.88.40 DOCKER_PORT=2375 ONLY_CONTAINERS=0 ONLY_ENDPOINTS=0 TIMEOUT=10 while [[ $# -gt 0 ]]; do case "$1" in -t|--target) TARGET="$2"; shift 2;; -p|--docker-port) DOCKER_PORT="$2"; shift 2;; --only-containers) ONLY_CONTAINERS=1; shift;; --only-endpoints) ONLY_ENDPOINTS=1; shift;; --timeout) TIMEOUT="$2"; shift 2;; *) echo "Unknown option: $1" >&2; exit 2;; esac done export DOCKER_HOST="tcp://${TARGET}:${DOCKER_PORT}" FAILED=0 fail() { printf ' [FAIL] %s\n' "$1"; FAILED=1; } ok() { printf ' [OK] %s\n' "$1"; } warn() { printf ' [WARN] %s\n' "$1"; } echo "== Linear Void environment check ==" echo "Target Docker host : $DOCKER_HOST" echo "Date : $(date -Iseconds)" # --------------------------------------------------------------------------- # 1. Docker Engine reachability # --------------------------------------------------------------------------- if [[ "$ONLY_ENDPOINTS" -eq 0 ]]; then echo "" echo "-- Docker Engine (${TARGET}:${DOCKER_PORT}) --" if ver=$(docker version --format '{{.Server.Version}}' 2>&1) && [[ "$ver" =~ [0-9] ]]; then ok "Docker Engine reachable (server version $ver)" else fail "Docker Engine not reachable: $ver" fi # ------------------------------------------------------------------------- # 2. Coolify helper stack # ------------------------------------------------------------------------- echo "" echo "-- Coolify managed-server helpers --" for c in coolify-proxy coolify-sentinel coolify-cloudflared; do if state=$(docker inspect "$c" --format '{{.State.Status}} ({{.State.Health.Status}})' 2>/dev/null); then if [[ "$state" =~ running.*(healthy|running) ]]; then ok "coolify helper: $c -> $state"; else warn "coolify helper: $c -> $state"; fi else warn "coolify helper: $c -> NOT FOUND (is this a Coolify-managed server?)" fi done # ------------------------------------------------------------------------- # 3. Linear Void containers # ------------------------------------------------------------------------- echo "" echo "-- Linear Void containers --" required=(linearvoid-playout linearvoid-chat linearvoid-nginx linearvoid-redis linearvoid-db linearvoid-prometheus linearvoid-grafana) running="$(docker ps --format '{{.Names}}' 2>/dev/null)" all="$(docker ps -a --format '{{.Names}}\t{{.Status}}' 2>/dev/null)" for name in "${required[@]}"; do if grep -qx "$name" <<<"$running"; then ok "container: $name is running" elif grep -q "^$name[[:space:]]" <<<"$all"; then status="$(grep "^$name[[:space:]]" <<<"$all" | head -1)" fail "container: $name EXISTS but not running -> $status" else fail "container: $name MISSING" fi done fi # --------------------------------------------------------------------------- # 4. Health endpoints (via Docker host) # --------------------------------------------------------------------------- if [[ "$ONLY_CONTAINERS" -eq 0 ]]; then echo "" echo "-- Health endpoints --" checks=( "chat /health|http://${TARGET}:3000/health" "nginx /health|http://${TARGET}:8081/health" "prometheus|http://${TARGET}:9090/-/healthy" "grafana /api/health|http://${TARGET}:3001/api/health" ) for entry in "${checks[@]}"; do name="${entry%%|*}"; url="${entry#*|}" code=$(curl -s -o /dev/null -w '%{http_code}' --max-time "$TIMEOUT" "$url" 2>/dev/null) if [[ "$code" == "200" ]]; then ok "$name -> 200"; elif [[ "$code" =~ ^[0-9]{3}$ ]]; then warn "$name -> $code"; else fail "$name -> unreachable"; fi done # ------------------------------------------------------------------------- # 5. Public endpoints (routed through the Docker host for reliable TLS) # ------------------------------------------------------------------------- echo "" echo "-- Public endpoints (via Docker host) --" pub=( "linearvoid.tv app|https://linearvoid.tv/" "media HLS manifest|https://media.linearvoid.tv/hls/playlist.m3u8" "coolify dashboard|https://coolify.allucanget.biz/" ) for entry in "${pub[@]}"; do name="${entry%%|*}"; url="${entry#*|}" code=$(docker run --rm curlimages/curl:latest -sS -o /dev/null -w '%{http_code}' --max-time "$TIMEOUT" -L "$url" 2>/dev/null | tr -d '[:space:]') if [[ "$code" =~ ^[0-9]{3}$ ]]; then ok "$name -> HTTP $code"; else warn "$name -> $code"; fi done fi # --------------------------------------------------------------------------- echo "" if [[ "$FAILED" -ne 0 ]]; then echo "RESULT: FAILED"; exit 1; fi echo "RESULT: OK" exit 0