SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
3 h agolast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%
5.4 KB · 83 lines shellscript
Raw Blame History
1#!/usr/bin/env bash2# deploy.sh data|crawl [--no-build] [--skip-migrate] [--no-backup-setup]3#4# data  : rsync → build (web/api/worker images) → up stores → run migrate (migrations + seed + ClickHouse DDL)5#         → up everything → install the dci-backup systemd timer → wait for http://10.67.0.60:8300/api/health6# crawl : rsync → build worker image → up → wait for http://10.68.0.2:8320/healthz7#8# Zero-downtime-ish: images are built before `up -d`, so containers are only recreated when their image or9# config changed; edge/web/api restart in a few seconds each and Caddy retries upstreams (lb_try_duration).10source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"1112target="${1:-}"; shift || true13check_target "$target"14build=1; migrate=1; backup_setup=115for a in "$@"; do16  case "$a" in17    --no-build) build=0 ;;18    --skip-migrate) migrate=0 ;;19    --no-backup-setup) backup_setup=0 ;;20    *) die "unknown flag $a" ;;21  esac22done23host="$(host_for "$target")"2425# ── preflight ────────────────────────────────────────────────────────────────────────────────────────26log "preflight ($target → $host)"27require_env_file "$target"28remote "$target" "command -v docker >/dev/null && docker compose version >/dev/null" || die "docker compose missing on $host"29if [[ $target == data ]]; then30  remote "$target" "ip -4 -o addr | grep -q ' $DATA_WG_IP/' && ip -4 -o addr | grep -q ' $DATA_PRIVATE_IP/'" \31    || warn "$DATA_WG_IP (wg1) and/or $DATA_PRIVATE_IP (dci0) not present on $host — port binds will fail unless ip_nonlocal_bind is set"32  # Docker must be able to bind the WireGuard IPs even if wg comes up after dockerd (reboot ordering).33  remote "$target" "printf 'net.ipv4.ip_nonlocal_bind = 1\n' | sudo tee /etc/sysctl.d/90-dci.conf >/dev/null && sudo sysctl -q -p /etc/sysctl.d/90-dci.conf"34else35  remote "$target" "ip -4 -o addr | grep -q ' $CRAWL_PRIVATE_IP/'" || warn "$CRAWL_PRIVATE_IP (dci0) not present on $host"36  remote "$target" "printf 'net.ipv4.ip_nonlocal_bind = 1\n' | sudo tee /etc/sysctl.d/90-dci.conf >/dev/null && sudo sysctl -q -p /etc/sysctl.d/90-dci.conf"37  remote "$target" "timeout 3 bash -c '</dev/tcp/$DATA_PRIVATE_IP/5432'" 2>/dev/null \38    || warn "cannot reach $DATA_PRIVATE_IP:5432 from $host — deploy the data node first / check dci0"39fi40ensure_remote_layout "$target"4142# ── sync + build ──────────────────────────────────────────────────────────────────────────────────────43sync_repo "$target"44if [[ $build == 1 ]]; then45  log "building images on $host"46  compose "$target" "build"47fi4849# ── up ────────────────────────────────────────────────────────────────────────────────────────────────50if [[ $target == data ]]; then51  log "starting stores"52  compose data "up -d postgres clickhouse redis minio"53  compose data "up -d minio-init"   # one-shot: bucket + app user54  if [[ $migrate == 1 ]]; then55    log "migrate (postgres migrations → seed → clickhouse ddl)"56    compose data "run --rm migrate"57  fi58  log "starting application + monitoring"59  compose data "up -d --remove-orphans"60  if [[ $backup_setup == 1 ]]; then61    log "backup: systemd timer + off-node key to $(host_for crawl)"62    remote data "sudo install -m 644 $REMOTE_DIR/deploy/systemd/dci-backup.service $REMOTE_DIR/deploy/systemd/dci-backup.timer /etc/systemd/system/ \63      && sudo systemctl daemon-reload && sudo systemctl enable --now dci-backup.timer"64    # key for the private-link rsync (ubuntu@BHS128 → ubuntu@10.68.0.2)65    remote data "test -f ~/.ssh/dci-backup || ssh-keygen -q -t ed25519 -N '' -C dci-backup@bhs128 -f ~/.ssh/dci-backup"66    pub="$(remote data "cat ~/.ssh/dci-backup.pub")"67    remote crawl "mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && grep -qF '$pub' ~/.ssh/authorized_keys || echo '$pub' >> ~/.ssh/authorized_keys; sudo mkdir -p $OFFSITE_DIR && sudo chown \$USER:\$USER $OFFSITE_DIR"68    remote data "ssh-keygen -F $CRAWL_PRIVATE_IP >/dev/null 2>&1 || ssh-keyscan -T 5 $CRAWL_PRIVATE_IP >> ~/.ssh/known_hosts 2>/dev/null" || warn "known_hosts for $CRAWL_PRIVATE_IP not populated"69    ok "backup timer installed: $(remote data 'systemctl list-timers dci-backup.timer --no-pager | sed -n 2p')"70  fi71  log "health"72  wait_http data "http://$DATA_WG_IP:8300/api/health" 60 5 || { compose data "ps"; compose data "logs --tail=50 api web edge"; die "edge/api not healthy"; }73  if curl -fsS -m 10 -o /dev/null "$PUBLIC_URL/api/health" 2>/dev/null; then ok "public: $PUBLIC_URL/api/health"; else warn "public route not answering yet — on BHS64: tunnelctl add www.datacenterindex.io BHS128:8300"; fi74else75  log "starting workers"76  compose crawl "up -d --remove-orphans"77  log "health"78  wait_http crawl "http://$CRAWL_PRIVATE_IP:8320/healthz" 36 5 || { compose crawl "ps"; compose crawl "logs --tail=80 worker"; die "worker not healthy"; }79fi8081compose "$target" "ps --format 'table {{.Service}}\t{{.Status}}\t{{.Ports}}'"82ok "deploy $target done"83