Backs up, ships compose/Caddyfile/verdaccio configs, migrates the shared registry
into verdaccio-ct, docker compose up, caddy reload, verifies npm.{ct,mc,quinn}.
Idempotent. Run via ! (shared multi-org host, not auto-mode).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
3.4 KiB
Bash
Executable file
61 lines
3.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# One-shot apply for the artifacts-host service stack (forge + producer-separated
|
|
# npm). Run from a machine with mesh/SSH reach: ./apply.sh
|
|
#
|
|
# It ships this dir's compose/Caddyfile/verdaccio configs to /opt/services on the
|
|
# artifacts host, lays out per-producer verdaccio dirs, migrates the shared
|
|
# registry's packages+auth into verdaccio-ct, brings the stack up, reloads the
|
|
# edge, and verifies. Idempotent + backs up before changing anything.
|
|
#
|
|
# The host is the SHARED multi-org artifacts box, so auto-mode can't run this for
|
|
# you — invoke it yourself (e.g. `! ./apply.sh` in-session).
|
|
set -euo pipefail
|
|
|
|
HOST="${ARTIFACTS_HOST:-134.199.243.61}"
|
|
JUMP="${ARTIFACTS_JUMP:-quinn-vps}"
|
|
KEY="${ARTIFACTS_KEY:-$HOME/.ssh/id_ed25519_1984}"
|
|
REMOTE="/opt/services"
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
SSH=(ssh -J "$JUMP" -i "$KEY" -o StrictHostKeyChecking=accept-new "root@$HOST")
|
|
rsh="ssh -J $JUMP -i $KEY -o StrictHostKeyChecking=accept-new"
|
|
say() { printf '\033[0;32m▸\033[0m %s\n' "$1"; }
|
|
|
|
say "Reachability check ($HOST via $JUMP)"
|
|
"${SSH[@]}" 'echo ok' >/dev/null || { echo "cannot reach root@$HOST via $JUMP"; exit 1; }
|
|
|
|
say "Backing up current compose + Caddyfile on the host"
|
|
"${SSH[@]}" "cd $REMOTE && cp -a docker-compose.yml docker-compose.yml.bak.\$(date +%s) 2>/dev/null || true; cp -a Caddyfile Caddyfile.bak.\$(date +%s) 2>/dev/null || true"
|
|
|
|
say "Laying out per-producer verdaccio dirs + migrating the shared registry into ct"
|
|
"${SSH[@]}" "cd $REMOTE
|
|
for p in ct mc quinn; do mkdir -p verdaccio-\$p/storage verdaccio-\$p/conf; done
|
|
# Migrate existing packages + htpasswd once (don't clobber a prior run).
|
|
if [ ! -e verdaccio-ct/storage/.migrated ]; then
|
|
if [ -d verdaccio/storage ]; then cp -a verdaccio/storage/. verdaccio-ct/storage/ 2>/dev/null || true
|
|
elif [ -d verdaccio ]; then cp -a verdaccio/. verdaccio-ct/storage/ 2>/dev/null || true; fi
|
|
touch verdaccio-ct/storage/.migrated
|
|
fi"
|
|
|
|
say "Shipping compose, Caddyfile, and verdaccio configs"
|
|
rsync -az -e "$rsh" "$DIR/docker-compose.yml" "root@$HOST:$REMOTE/docker-compose.yml"
|
|
rsync -az -e "$rsh" "$DIR/Caddyfile" "root@$HOST:$REMOTE/Caddyfile"
|
|
rsync -az -e "$rsh" "$DIR/verdaccio-ct.config.yaml" "root@$HOST:$REMOTE/verdaccio-ct/conf/config.yaml"
|
|
rsync -az -e "$rsh" "$DIR/verdaccio-downstream.config.yaml" "root@$HOST:$REMOTE/verdaccio-mc/conf/config.yaml"
|
|
rsync -az -e "$rsh" "$DIR/verdaccio-downstream.config.yaml" "root@$HOST:$REMOTE/verdaccio-quinn/conf/config.yaml"
|
|
|
|
say "Bringing the stack up + reloading the edge"
|
|
"${SSH[@]}" "cd $REMOTE
|
|
docker compose up -d
|
|
docker exec services-caddy-1 caddy validate --config /etc/caddy/Caddyfile
|
|
docker exec services-caddy-1 caddy reload --config /etc/caddy/Caddyfile"
|
|
|
|
say "Verifying"
|
|
sleep 3
|
|
"${SSH[@]}" '
|
|
echo -n " npm.ct ping: "; curl -fsS https://npm.ct.uvlava.com/-/ping >/dev/null && echo ok || echo FAIL
|
|
echo -n " ct @cocotte: "; curl -fsS https://npm.ct.uvlava.com/@cocotte/ai-harness >/dev/null && echo "serves @cocotte/ai-harness" || echo "(not found — check migration)"
|
|
echo -n " mc proxy: "; curl -fsS https://npm.mc.uvlava.com/-/ping >/dev/null && echo ok || echo "FAIL (npm.mc DNS?)"
|
|
echo -n " quinn proxy: "; curl -fsS https://npm.quinn.uvlava.com/-/ping >/dev/null && echo ok || echo "FAIL (npm.quinn DNS?)"
|
|
'
|
|
say "Done. Point consumers at https://npm.ct.uvlava.com/ (see README)."
|