spb/earth-now Public License
earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.
TypeScript 93%
Shell 2.3%
SQL 1.4%
JavaScript 1.3%
Dockerfile 1.2%
CSS 0.8%
1#!/usr/bin/env bash2# earth-now.co3# Author: Simon-Pierre Boucher4# Contact: contact@spboucher.ai5# File: infra/deploy-m3u96b-docker.sh6# Purpose: Deploy to production node m3u96b — rsync, docker compose up, then MANDATORY health checks against www.earth-now.co78set -euo pipefail910REMOTE="m3u96b"11REMOTE_DIR="~/earth-now"12BASE_URL="https://www.earth-now.co"13REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"1415ok() { printf '✓ %s\n' "$1"; }16fail() { printf '✗ %s\n' "$1"; }1718echo "== earth-now deploy → ${REMOTE} =="1920# --- 1. Sync sources (build happens on the node inside Docker) ---------------21echo "-- rsync ${REPO_ROOT}/ → ${REMOTE}:${REMOTE_DIR}/"22rsync -az --delete \23 --exclude "node_modules" \24 --exclude ".next" \25 --exclude "dist" \26 --exclude ".turbo" \27 --exclude ".git" \28 --exclude "data/" \29 "${REPO_ROOT}/" "${REMOTE}:${REMOTE_DIR}/"30ok "rsync complete"3132# --- 2. Build & (re)start the stack -------------------------------------------33echo "-- docker compose up -d --build on ${REMOTE}"34ssh "${REMOTE}" "cd ${REMOTE_DIR} && docker compose -f infra/docker-compose.prod.yml up -d --build"35ok "docker compose up"3637# --- 3. Health checks (per CLAUDE.md the deploy is NOT done until both pass) --38FAILED=03940echo "-- health check: GET ${BASE_URL}/api/health"41if curl -fsS --max-time 15 "${BASE_URL}/api/health" > /dev/null; then42 ok "api health returned 200"43else44 fail "api health check failed (${BASE_URL}/api/health)"45 FAILED=146fi4748echo "-- health check: hold SSE ${BASE_URL}/sse/health ≥ 10 s"49SSE_START=$(date +%s)50SSE_OUTPUT="$(curl -sN --max-time 12 "${BASE_URL}/sse/health" | head -c 100 || true)"51SSE_ELAPSED=$(( $(date +%s) - SSE_START ))52if [ -n "${SSE_OUTPUT}" ]; then53 ok "SSE stream produced output (held ~${SSE_ELAPSED}s, first bytes: $(printf '%s' "${SSE_OUTPUT}" | head -c 40 | tr -d '\n'))"54else55 fail "SSE health check produced no output after ${SSE_ELAPSED}s (${BASE_URL}/sse/health)"56 FAILED=157fi5859if [ "${FAILED}" -ne 0 ]; then60 fail "deploy NOT healthy — investigate before declaring the deploy done"61 exit 162fi63ok "deploy to ${REMOTE} complete and healthy → ${BASE_URL}"64