ci: take the deploy target out of the public workflow
CI / verify (push) Successful in 46s
CI / deploy (push) Failing after 1m18s

This repo is public, so .gitea/workflows/ci.yml was publishing the web
host's tailnet address in a plaintext env: block, together with the deploy
account, the checkout path and the unit restarted under sudo -- a complete
map of the deploy for any anonymous reader.

Host, account, path and service now come from repo secrets (DEPLOY_HOST,
DEPLOY_USER, DEPLOY_PATH, DEPLOY_SERVICE), which Gitea masks in run logs.
The path and unit name are passed to the remote shell as positional args
inside a quoted heredoc so they are never interpolated into the log either.
The deploy key secret is renamed CLOUD2_SSH_KEY -> DEPLOY_SSH_KEY to match;
it was never actually set, which is why every deploy run so far is red.

The rest of docs/DEPLOY.md already used the web-host/build-host pseudonyms;
this drops the remaining absolute deploy-account paths from its prose.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AaUFYkUTsJn1fnJ89qbvW
This commit is contained in:
2026-09-15 12:18:22 -07:00
co-authored by Claude Opus 5
parent 68a436d7ea
commit 91a086e723
2 changed files with 41 additions and 16 deletions
+38 -13
View File
@@ -5,8 +5,17 @@
# `needs:`, because Gitea's cross-workflow triggers are less reliable than GitHub's. A red
# build cannot deploy.
#
# Requires one repo secret: CLOUD2_SSH_KEY — the private half of a deploy key whose public
# half is in ubuntu@web-host's authorized_keys.
# This repo is PUBLIC, so nothing here may name the deploy target. The host, the account,
# the checkout path and the service name all come from repo secrets; the workflow only
# describes the shape of the deploy.
#
# Requires these repo secrets:
# DEPLOY_SSH_KEY — private half of a deploy key whose public half is in the deploy
# account's authorized_keys on the web host
# DEPLOY_HOST — the web host to deploy to
# DEPLOY_USER — the account to ssh in as
# DEPLOY_PATH — the checkout on the web host that is reset to origin/main
# DEPLOY_SERVICE — the systemd unit restarted after the build
name: CI
@@ -17,9 +26,6 @@ on:
branches: [main]
workflow_dispatch:
env:
CLOUD2_HOST: 100.92.185.76
jobs:
verify:
runs-on: ubuntu-latest
@@ -68,26 +74,43 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up SSH
env:
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
mkdir -p ~/.ssh
echo "${{ secrets.CLOUD2_SSH_KEY }}" > ~/.ssh/deploy_key
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H "$CLOUD2_HOST" >> ~/.ssh/known_hosts 2>/dev/null
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null
- name: Deploy to web-host
- name: Deploy to the web host
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
run: |
ssh -i ~/.ssh/deploy_key -o BatchMode=yes ubuntu@"$CLOUD2_HOST" bash -s <<'REMOTE'
# The path and unit name are passed as positional args, not interpolated:
# the heredoc is quoted so the runner never expands them into the log.
ssh -i ~/.ssh/deploy_key -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
bash -s -- "$DEPLOY_PATH" "$DEPLOY_SERVICE" <<'REMOTE'
set -euo pipefail
cd /home/ubuntu/workspace/bench.karti.ai
checkout="$1"
service="$2"
cd "$checkout"
git fetch origin -q
git reset --hard origin/main -q
cd site
npm install --no-audit --no-fund
npm run build
sudo systemctl restart bench-karti
sudo systemctl restart "$service"
REMOTE
- name: Verify the deploy
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
run: |
for i in $(seq 1 20); do
if curl -sf https://bench.karti.ai/api/health | grep -q '"ok":true'; then
@@ -97,6 +120,8 @@ jobs:
sleep 3
done
echo "::error::bench.karti.ai did not come back healthy after deploy"
ssh -i ~/.ssh/deploy_key -o BatchMode=yes ubuntu@"$CLOUD2_HOST" \
'sudo journalctl -u bench-karti -n 40 --no-pager' || true
ssh -i ~/.ssh/deploy_key -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
bash -s -- "$DEPLOY_SERVICE" <<'REMOTE' || true
sudo journalctl -u "$1" -n 40 --no-pager
REMOTE
exit 1
+3 -3
View File
@@ -12,7 +12,7 @@ What that leaves on the box:
- Caddy vhost for `bench.karti.ai` is now `redir https://lumbridgecorp.com/bench permanent`
(a pre-change Caddyfile backup is at `/etc/caddy/Caddyfile.bak-bench-<timestamp>`)
- DNS `bench.karti.ai A 170.9.14.61` and the Let's Encrypt cert stay — the redirect needs both
- checkout at `/home/ubuntu/workspace/bench.karti.ai` remains, now on `origin` =
- checkout at `~/workspace/bench.karti.ai` remains, now on `origin` =
`karti/lumbridge-bench`; the `bench-karti` unit is stopped and disabled, not removed
**To bring a Bench UI back up**, deploy it as part of Lumbridge rather than reviving the subdomain.
@@ -45,13 +45,13 @@ forever. Either add the `www` records or drop them from their vhosts.
| repo | `karti/lumbridge-bench` on gitea, **private** |
| host | web-host, port **8909** |
| service | `bench-karti` compatibility service (systemd) |
| checkout | `/home/ubuntu/workspace/bench.karti.ai` compatibility path |
| checkout | `~/workspace/bench.karti.ai` compatibility path |
| domain | `bench.karti.ai` → web-host, DNS via oci on build-host (profile `cloud2-sanjose`) |
## One-time setup on web-host
```bash
cd /home/ubuntu/workspace
cd ~/workspace
git clone https://gitea.example.internal:8444/karti/lumbridge-bench.git bench.karti.ai
cd bench.karti.ai/site
cp .env.example .env.local # loopback Lumbridge control plane