Monorepo for Aesthetic.Computer aesthetic.computer
at main 181 lines 5.8 kB view raw
1#!/usr/bin/env fish 2# Deploy dp1-feed (SQLite mode) to silo.aesthetic.computer 3# 4# Usage: 5# fish deploy-silo.fish # Full deploy (build, upload, restart) 6# fish deploy-silo.fish --landing # Landing page only (no restart) 7# fish deploy-silo.fish --setup # First-time setup (create dirs, systemd service, env) 8 9set RED '\033[0;31m' 10set GREEN '\033[0;32m' 11set YELLOW '\033[1;33m' 12set NC '\033[0m' 13 14set SCRIPT_DIR (dirname (status --current-filename)) 15set VAULT_DIR "$SCRIPT_DIR/../aesthetic-computer-vault" 16set SSH_KEY "$VAULT_DIR/home/.ssh/id_rsa" 17set SILO_HOST "silo.aesthetic.computer" 18set SILO_USER "root" 19set REMOTE_DIR "/opt/dp1-feed" 20set DP1_DIR "$SCRIPT_DIR/dp1-feed" 21 22set SETUP false 23set LANDING_ONLY false 24if contains -- --setup $argv 25 set SETUP true 26end 27if contains -- --landing $argv 28 set LANDING_ONLY true 29end 30 31# Check for SSH key 32if not test -f $SSH_KEY 33 echo -e "$RED x SSH key not found: $SSH_KEY$NC" 34 exit 1 35end 36 37# Test SSH connection 38echo -e "$GREEN-> Testing SSH connection to $SILO_HOST...$NC" 39if not ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o ConnectTimeout=10 $SILO_USER@$SILO_HOST "echo ok" &>/dev/null 40 echo -e "$RED x Cannot connect to $SILO_HOST$NC" 41 exit 1 42end 43echo -e "$GREEN Connected.$NC" 44 45if test $LANDING_ONLY = true 46 echo -e "$GREEN-> Uploading landing-page.html (no restart)...$NC" 47 scp -i $SSH_KEY -o StrictHostKeyChecking=no \ 48 $SCRIPT_DIR/landing-page.html \ 49 $SILO_USER@$SILO_HOST:$REMOTE_DIR/ 50 ssh -i $SSH_KEY $SILO_USER@$SILO_HOST "chown dp1feed:dp1feed $REMOTE_DIR/landing-page.html" 51 echo -e "$GREEN Landing page deployed.$NC" 52 exit 0 53end 54 55if test $SETUP = true 56 # First-time setup: create dirs, systemd service, generate keys 57 echo -e "$GREEN-> First-time setup on $SILO_HOST...$NC" 58 59 ssh -i $SSH_KEY $SILO_USER@$SILO_HOST " 60 # Create app directory and user 61 mkdir -p $REMOTE_DIR/data 62 id -u dp1feed &>/dev/null || useradd -r -s /bin/false dp1feed 63 chown -R dp1feed:dp1feed $REMOTE_DIR 64 65 # Install Node.js 22 if not present 66 if ! command -v node &>/dev/null || [ \$(node -v | cut -d. -f1 | tr -d v) -lt 22 ]; then 67 curl -fsSL https://deb.nodesource.com/setup_22.x | bash - 68 apt-get install -y nodejs 69 fi 70 echo 'Node:' \$(node -v) 71 72 # Install build tools for better-sqlite3 73 apt-get install -y python3 make g++ 2>/dev/null 74 75 # Create systemd service 76 cat > /etc/systemd/system/dp1-feed.service << 'UNIT' 77[Unit] 78Description=DP-1 Feed Operator API (SQLite) 79After=network.target 80 81[Service] 82Type=simple 83User=dp1feed 84WorkingDirectory=/opt/dp1-feed 85ExecStart=/usr/bin/node dist/server-sqlite.js 86EnvironmentFile=/opt/dp1-feed/.env 87Restart=always 88RestartSec=5 89 90[Install] 91WantedBy=multi-user.target 92UNIT 93 94 systemctl daemon-reload 95 systemctl enable dp1-feed 96 echo 'Systemd service created and enabled.' 97 " 98 99 # Read API secret from vault (shared with silo dashboard) 100 echo -e "$GREEN-> Generating .env...$NC" 101 set VAULT_FEED_ENV "$VAULT_DIR/feed/.env" 102 if test -f $VAULT_FEED_ENV 103 set API_SECRET (grep '^FEED_API_SECRET=' $VAULT_FEED_ENV | sed 's/^FEED_API_SECRET=//') 104 end 105 if test -z "$API_SECRET" 106 set API_SECRET (openssl rand -hex 32) 107 echo -e "$YELLOW No vault secret found, generated random API_SECRET$NC" 108 end 109 set ED25519_KEY (node -e " 110 const { generateKeyPairSync } = require('crypto'); 111 const kp = generateKeyPairSync('ed25519'); 112 const der = kp.privateKey.export({ type: 'pkcs8', format: 'der' }); 113 console.log(Buffer.from(der).toString('hex')); 114 " 2>/dev/null; or echo "302e020100300506032b6570042204205e42cad90e34efb36d84b8dbbcf15777ac33f4126a80c087cdedfb030138ac6f") 115 116 ssh -i $SSH_KEY $SILO_USER@$SILO_HOST "cat > $REMOTE_DIR/.env << EOF 117API_SECRET=$API_SECRET 118ED25519_PRIVATE_KEY=$ED25519_KEY 119SQLITE_DB_PATH=/opt/dp1-feed/data/dp1-feed.db 120ENVIRONMENT=sqlite 121SELF_HOSTED_DOMAINS=silo.aesthetic.computer:8787,localhost:8787 122PORT=8787 123EOF 124 chown dp1feed:dp1feed $REMOTE_DIR/.env 125 chmod 600 $REMOTE_DIR/.env" 126 127 echo -e "$GREEN Setup complete. Run 'fish deploy-silo.fish' to deploy.$NC" 128 exit 0 129end 130 131# Regular deploy: build locally, upload, restart 132echo -e "$GREEN-> Building dp1-feed (SQLite)...$NC" 133cd $DP1_DIR 134npm run sqlite:build 2>&1 | tail -1 135 136if test $status -ne 0 137 echo -e "$RED x Build failed$NC" 138 exit 1 139end 140 141echo -e "$GREEN-> Uploading to $SILO_HOST...$NC" 142ssh -i $SSH_KEY -o StrictHostKeyChecking=no $SILO_USER@$SILO_HOST "mkdir -p $REMOTE_DIR/dist" 143scp -i $SSH_KEY -o StrictHostKeyChecking=no \ 144 $DP1_DIR/dist/server-sqlite.js \ 145 $SILO_USER@$SILO_HOST:$REMOTE_DIR/dist/ 146scp -i $SSH_KEY -o StrictHostKeyChecking=no \ 147 $DP1_DIR/package.json \ 148 $DP1_DIR/package-lock.json \ 149 $SILO_USER@$SILO_HOST:$REMOTE_DIR/ 150 151# Upload landing page 152echo -e "$GREEN-> Uploading landing page...$NC" 153scp -i $SSH_KEY -o StrictHostKeyChecking=no \ 154 $SCRIPT_DIR/landing-page.html \ 155 $SILO_USER@$SILO_HOST:$REMOTE_DIR/ 156 157echo -e "$GREEN-> Installing dependencies & restarting...$NC" 158ssh -i $SSH_KEY $SILO_USER@$SILO_HOST " 159 chown -R dp1feed:dp1feed $REMOTE_DIR 160 cd $REMOTE_DIR && npm install --production --silent 2>&1 | tail -1 161 systemctl restart dp1-feed 162 sleep 2 163 systemctl is-active dp1-feed 164" 165 166set STATUS $status 167if test $STATUS -eq 0 168 echo -e "$GREEN dp1-feed is running.$NC" 169 170 # Quick health check 171 sleep 1 172 ssh -i $SSH_KEY $SILO_USER@$SILO_HOST "curl -s http://localhost:8787/api/v1/health" 173 echo "" 174else 175 echo -e "$RED x dp1-feed failed to start. Check logs:$NC" 176 echo -e "$YELLOW ssh -i $SSH_KEY $SILO_USER@$SILO_HOST journalctl -u dp1-feed -n 30$NC" 177 exit 1 178end 179 180echo "" 181echo -e "$GREEN Done. dp1-feed deployed to $SILO_HOST:8787$NC"