ReviewOS

stacks/smakelo

B0: Scaffold, config, and CI tenant deploy

#2
Open chris opened this 9 days ago ·
9 days ago

Part of #1.

  • Scaffold via buddy new smakelo (plain: no --minimal, no --with-core), SQLite in config/database.ts (.env: DB_CONNECTION=sqlite, DB_DATABASE_PATH=database/stacks.sqlite - the scaffold defaults to postgres)
  • Add deps: ts-qr-codes, ts-maps; pin @stacksjs/* to the release carrying the upstream WPs
  • Configure config/app|payment|realtime|search-engine|i18n; locales/ en/de/nl
  • Push to stacksjs/smakelo; GitHub Actions push-to-main tarball deploy as a tenant on the Hetzner stacks box (smakelo.stacksjs.com preview; real domain later). Mind the known deploy traps: preStart mkdir, PORT_API env, pick free ports from ss -lntp on the box (not from config files), and register the gateway hostname + DNS record together
  • Demo hygiene from day 1: robots.txt disallow + noindex meta
9 days ago

Deployed and live at https://smakelo.stacksjs.com (7b809c0).

Done: scaffold, SQLite, app identity, ts-maps + ts-qr-codes, en/de/nl locales, demo guards (noindex meta on every page, robots.txt, banner), tenant config on the stacks box (ports 3210/3218 taken from a live ss -lntp, database at /var/lib/smakelo outside the release dirs), DNS + TLS + CDN reconciled by the deploy.

Two things still open, tracked here:

  • Push-to-deploy CI. Deploys are currently run by hand with buddy deploy --prod --yes. The tarball workflow the other tenants use is not wired up yet.
  • Cloudflare serves its own managed robots.txt for the stacksjs.com zone, so ours never reaches a crawler. The per-page noindex is what actually prevents indexing and it is in place, but the zone setting is Chris's call since it affects every site on the zone.
9 days ago

CI is green for the first time, and the Deploy workflow is wired and waiting on two secrets.

CI had been red on every push since the first one. I had not noticed because I was deploying by hand. The typecheck job failed on the scaffolded app/Scheduler.ts, which schedules a job called 'Inspire' that does not exist in this app and never did. The framework's scheduler types exist precisely to catch that (their own doc comment cites a misspelled job name that failed at 3am), so the guard worked and nobody was reading the check. Fixed by scheduling real work instead: RollCsaBoxes.

The deploy workflow already does the right thing. It is gated on CI rather than on the push, since buddy deploy activates a release atomically and the failure mode of shipping an untested commit is a live site running it. It currently finishes green with a notice naming what is missing, which is better than a red X.

To turn on push-to-deploy, two secrets are needed — both are credentials, so they are yours to add rather than mine:

gh secret set DEPLOY_SSH_KEY --repo stacksjs/smakelo < ~/.ssh/id_ed25519
gh secret set DOTENV_PRIVATE_KEY_PRODUCTION --repo stacksjs/smakelo

The second value is in .env.keys. Three optional ones (CLOUDFLARE_API_TOKEN, PORKBUN_API_KEY, PORKBUN_SECRET_KEY) only matter for DNS and CDN reconciliation; without them the deploy still ships, it just will not touch DNS.

Until then, deploys keep happening the way they have been: ./buddy deploy from the working copy, which is what has put every change on smakelo.stacksjs.com so far.

One caveat carried over from erbamarkets: buddy deploy tars the working directory, so a local deploy ships uncommitted files. CI is the only clean release path, which is another reason to add the two secrets.

Sign in to comment on this issue.