#!/usr/bin/env bash # host-readiness-check.sh — Validate target host before Matrix/Conduit deployment # Usage: ./host-readiness-check.sh [DOMAIN] # Issue: #166 / #183 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOMAIN="${1:-${MATRIX_DOMAIN:-}}" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' PASS=0 FAIL=0 WARN=0 pass() { echo -e "${GREEN}[PASS]${NC} $*"; ((PASS++)); } fail() { echo -e "${RED}[FAIL]${NC} $*"; ((FAIL++)); } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; ((WARN++)); } log() { echo -e "\n==> $*"; } log "Matrix/Conduit Host Readiness Check" log "====================================" # === Domain check === if [[ -z "$DOMAIN" ]]; then fail "DOMAIN not specified. Usage: ./host-readiness-check.sh matrix.timmytime.net" exit 1 else pass "Domain specified: $DOMAIN" fi # === Docker === log "Checking Docker..." if command -v docker &>/dev/null; then DOCKER_VER=$(docker --version) pass "Docker installed: $DOCKER_VER" else fail "Docker not installed" fi if docker compose version &>/dev/null || docker-compose --version &>/dev/null; then pass "Docker Compose available" else fail "Docker Compose not available" fi if docker info &>/dev/null; then pass "Docker daemon is running" else fail "Docker daemon is not running or user lacks permissions" fi # === Ports === log "Checking ports..." for port in 80 443 8448; do if ss -tln | grep -q ":$port "; then warn "Port $port is already in use (may conflict)" else pass "Port $port is available" fi done # === DNS Resolution === log "Checking DNS..." RESOLVED_IP=$(dig +short "$DOMAIN" || true) if [[ -n "$RESOLVED_IP" ]]; then HOST_IP=$(curl -s ifconfig.me || true) if [[ "$RESOLVED_IP" == "$HOST_IP" ]]; then pass "DNS A record resolves to this host ($HOST_IP)" else warn "DNS A record resolves to $RESOLVED_IP (this host is $HOST_IP)" fi else fail "DNS A record for $DOMAIN not found" fi # === Disk Space === log "Checking disk space..." AVAILABLE_GB=$(df -BG "$SCRIPT_DIR" | awk 'NR==2 {gsub(/G/,""); print $4}') if [[ "$AVAILABLE_GB" -ge 20 ]]; then pass "Disk space: ${AVAILABLE_GB}GB available" else warn "Disk space: ${AVAILABLE_GB}GB available (recommended: 20GB+)" fi # === Memory === log "Checking memory..." MEM_GB=$(free -g | awk '/^Mem:/ {print $2}') if [[ "$MEM_GB" -ge 2 ]]; then pass "Memory: ${MEM_GB}GB" else warn "Memory: ${MEM_GB}GB (recommended: 2GB+)" fi # === Reverse proxy detection === log "Checking reverse proxy..." if command -v caddy &>/dev/null; then pass "Caddy installed" elif command -v nginx &>/dev/null; then pass "Nginx installed" elif ss -tln | grep -q ":80 " || ss -tln | grep -q ":443 "; then warn "No Caddy/Nginx found, but something is bound to 80/443" else warn "No reverse proxy detected (Caddy or Nginx recommended)" fi # === Summary === log "====================================" echo -e "Results: ${GREEN}$PASS passed${NC}, ${YELLOW}$WARN warnings${NC}, ${RED}$FAIL failures${NC}" if [[ $FAIL -gt 0 ]]; then echo "" echo "Host is NOT ready for deployment. Fix failures above, then re-run." exit 1 else echo "" echo "Host looks ready. Next step: ./deploy-matrix.sh $DOMAIN" exit 0 fi