reworked stack

This commit is contained in:
johba 2025-10-07 21:57:32 +00:00
parent 6cbb1781ce
commit f7ef56f65f
12 changed files with 853 additions and 458 deletions

View file

@ -3,20 +3,82 @@ set -euo pipefail
cd "$(dirname "$0")/.."
# Timeout constants (in seconds)
readonly ANVIL_TIMEOUT=30 # Anvil starts fast
readonly POSTGRES_TIMEOUT=20 # Database init is quick
readonly BOOTSTRAP_TIMEOUT=60 # Contract deployment + seeding
readonly PONDER_TIMEOUT=90 # Must index bootstrap events
readonly WEBAPP_TIMEOUT=90 # npm install + Vite startup
readonly CADDY_TIMEOUT=10 # Proxy starts instantly
readonly POLL_INTERVAL=2 # Check health every N seconds
PID_FILE=/tmp/kraiken-watcher.pid
PROJECT_NAME=${COMPOSE_PROJECT_NAME:-$(basename "$PWD")}
start_stack() {
if [[ -f "$PID_FILE" ]]; then
local existing_pid
existing_pid=$(cat "$PID_FILE")
if kill -0 "$existing_pid" 2>/dev/null; then
echo "Stopping existing kraiken-lib watcher ($existing_pid)..."
kill "$existing_pid" 2>/dev/null || true
wait "$existing_pid" 2>/dev/null || true
cleanup_existing() {
# Kill any existing watch scripts
pkill -f "watch-kraiken-lib.sh" 2>/dev/null || true
pkill -f "inotifywait.*$(pwd)/kraiken-lib" 2>/dev/null || true
# Remove PID file
rm -f "$PID_FILE"
# Kill zombie podman processes
pkill -9 -f "podman wait.*harb_" 2>/dev/null || true
# Remove any existing containers (suppress errors if they don't exist)
echo " Cleaning up existing containers..."
podman ps -a --filter "name=harb_" --format "{{.Names}}" 2>/dev/null | \
xargs -r podman rm -f 2>&1 | grep -v "Error.*no container" || true
}
# Wait for container to be healthy (via healthcheck)
wait_for_healthy() {
local container=$1
local timeout_sec=$2
local max_attempts=$((timeout_sec / POLL_INTERVAL))
local start_time=$(date +%s)
for i in $(seq 1 "$max_attempts"); do
if podman healthcheck run "$container" &>/dev/null; then
local elapsed=$(($(date +%s) - start_time))
echo "$container ready (${elapsed}s)"
return 0
fi
rm -f "$PID_FILE"
fi
sleep "$POLL_INTERVAL"
done
echo "ERROR: $container failed to become healthy after ${timeout_sec}s"
return 1
}
# Wait for container to exit (used for bootstrap)
wait_for_exited() {
local container=$1
local timeout_sec=$2
local max_attempts=$((timeout_sec / POLL_INTERVAL))
local start_time=$(date +%s)
for i in $(seq 1 "$max_attempts"); do
local status
status=$(podman inspect "$container" --format='{{.State.Status}}' 2>/dev/null || echo "unknown")
if [[ "$status" == "exited" ]]; then
local elapsed=$(($(date +%s) - start_time))
echo "$container completed (${elapsed}s)"
return 0
fi
sleep "$POLL_INTERVAL"
done
echo "ERROR: $container failed to complete after ${timeout_sec}s"
return 1
}
start_stack() {
local stack_start_time=$(date +%s)
# Clean up any existing processes first
cleanup_existing
# Show branch if set
if [[ -n "${GIT_BRANCH:-}" ]]; then
@ -27,84 +89,53 @@ start_stack() {
./scripts/build-kraiken-lib.sh
echo "Starting stack..."
# Start services in strict dependency order with explicit create+start
# This avoids podman dependency graph issues
# Create all containers first (without starting)
echo " Creating containers..."
podman-compose up --no-start 2>&1 | grep -v "STEP\|Copying\|Writing\|Getting\|fetch\|Installing\|Executing" || true
# Phase 1: Start base services (no dependencies)
echo " Starting anvil & postgres..."
podman-compose start anvil postgres >/dev/null 2>&1
podman-compose up -d anvil postgres 2>&1 | grep -v "STEP\|Copying\|Writing\|Getting\|fetch\|Installing\|Executing" || true
# Wait for base services to be healthy
echo " Waiting for anvil & postgres..."
for i in {1..30}; do
anvil_healthy=$(podman healthcheck run harb_anvil_1 >/dev/null 2>&1 && echo "yes" || echo "no")
postgres_healthy=$(podman healthcheck run harb_postgres_1 >/dev/null 2>&1 && echo "yes" || echo "no")
if [[ "$anvil_healthy" == "yes" ]] && [[ "$postgres_healthy" == "yes" ]]; then
break
fi
sleep 2
done
wait_for_healthy harb_anvil_1 "$ANVIL_TIMEOUT" || exit 1
wait_for_healthy harb_postgres_1 "$POSTGRES_TIMEOUT" || exit 1
# Phase 2: Start bootstrap (depends on anvil & postgres healthy)
echo " Starting bootstrap..."
podman-compose start bootstrap >/dev/null 2>&1
podman-compose up -d bootstrap >/dev/null 2>&1
# Wait for bootstrap to complete
echo " Waiting for bootstrap..."
for i in {1..60}; do
bootstrap_status=$(podman inspect harb_bootstrap_1 --format='{{.State.Status}}')
if [[ "$bootstrap_status" == "exited" ]]; then
break
fi
sleep 2
done
wait_for_exited harb_bootstrap_1 "$BOOTSTRAP_TIMEOUT" || exit 1
# Phase 3: Start ponder (depends on bootstrap completed)
echo " Starting ponder..."
podman-compose start ponder >/dev/null 2>&1
podman-compose up -d ponder >/dev/null 2>&1
# Wait for ponder to be healthy
echo " Waiting for ponder..."
for i in {1..60}; do
ponder_healthy=$(podman healthcheck run harb_ponder_1 >/dev/null 2>&1 && echo "yes" || echo "no")
if [[ "$ponder_healthy" == "yes" ]]; then
break
fi
sleep 2
done
wait_for_healthy harb_ponder_1 "$PONDER_TIMEOUT" || exit 1
# Phase 4: Start frontend services (depend on ponder healthy)
echo " Starting webapp, landing, txn-bot..."
podman-compose start webapp landing txn-bot >/dev/null 2>&1
podman-compose up -d webapp landing txn-bot >/dev/null 2>&1
wait_for_healthy harb_webapp_1 "$WEBAPP_TIMEOUT" || exit 1
# Phase 5: Start caddy (depends on frontend services)
sleep 5
echo " Starting caddy..."
podman-compose start caddy >/dev/null 2>&1
podman-compose up -d caddy >/dev/null 2>&1
echo "Watching for kraiken-lib changes..."
./scripts/watch-kraiken-lib.sh &
echo $! > "$PID_FILE"
wait_for_healthy harb_caddy_1 "$CADDY_TIMEOUT" || exit 1
if [[ -z "${SKIP_WATCH:-}" ]]; then
echo "Watching for kraiken-lib changes..."
./scripts/watch-kraiken-lib.sh &
echo $! > "$PID_FILE"
fi
local total_time=$(($(date +%s) - stack_start_time))
echo ""
echo "[ok] Stack started"
echo "[ok] Stack started in ${total_time}s"
echo " Web App: http://localhost:8081/app/"
echo " GraphQL: http://localhost:8081/graphql"
}
stop_stack() {
if [[ -f "$PID_FILE" ]]; then
local watcher_pid
watcher_pid=$(cat "$PID_FILE")
if kill "$watcher_pid" 2>/dev/null; then
wait "$watcher_pid" 2>/dev/null || true
fi
rm -f "$PID_FILE"
fi
cleanup_existing
podman-compose down
echo "[ok] Stack stopped"
}