Files
ladill-pos/DEPLOY.md
T
isaaccladandClaude Opus 4.8 57862acb47
Deploy Ladill POS / deploy (push) Successful in 24s
Retarget deploy pipeline to POS and guard against cross-service clobber
The pipeline was copied from Ladill Mini and still deployed into
/var/www/ladill-mini, so the first POS push overwrote mini.ladill.com.
Retarget every mini reference to pos (app root, archive/workspace names,
concurrency group, nginx subdomain, supervisor worker), add a guard step
that fails the run unless basename(LADILL_APP_ROOT) matches the repo name,
and document the incident + a forking checklist in DEPLOY.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 23:16:00 +00:00

3.1 KiB

Ladill POS — deploy runbook

Standalone in-store register at pos.ladill.com. Charges via Ladill Pay (source_service: pos, fee_tier: sales).

Platform wiring

  1. OIDC client: php artisan passport:client on monolith — redirect https://pos.ladill.com/sso/callback
  2. Env keys on monolith: BILLING_API_KEY_POS, PAY_API_KEY_POS, IDENTITY_API_KEY_POS
  3. Env on POS app: matching consumer keys + LADILL_SSO_CLIENT_*
  4. Database: ladill_pos (MySQL) — migrations via deploy script
  5. Marketing: php scripts/ensure-app-entry-routes.php (includes ladill-pos)

Deploy

Same release model as Mini/Merchant — see deploy/deploy.sh. Pushing to main triggers .gitea/workflows/deploy.yml on the host deploy runner, which builds a release and deploys into /var/www/ladill-pos.

⚠️ Forking this pipeline (read before copying to a new service)

This workflow was bootstrapped by copying Mini's. If you copy .gitea/workflows/deploy.yml, deploy/deploy.sh, or DEPLOY.md to a new service, retarget EVERY mini/pos reference, or the new repo's pipeline will deploy its code on top of the service you copied from.

Things that must match the new service (search for the old slug and replace all):

  • deploy.yml: name:, concurrency.group, RELEASE_ARCHIVE, WORKSPACE, LADILL_APP_ROOT, the nginx step subdomain (pos --app /var/www/ladill-pos/current)
  • deploy.sh: APP_ROOT default and the supervisorctl restart <service>-worker:* name

A guard step in deploy.yml enforces basename(LADILL_APP_ROOT) == <repo name> and fails the run on a mismatch — keep repo name and app dir name identical (ladill-pos/var/www/ladill-pos).

Incident 2026-06-24: the initial POS pipeline still pointed at /var/www/ladill-mini, so the first POS push overwrote mini.ladill.com (POS code + a stray create_pos_tables migration against the ladill_mini DB). Remediated by repointing mini's current symlink to the last genuine Mini release and dropping the 4 stray pos_* tables. The guard step above exists to make this impossible to repeat.

Server prerequisites (one-time, as root)

Done for pos.ladill.com; replicate for any new service:

  1. MySQL: CREATE DATABASE ladill_pos + user ladill_pos@127.0.0.1 (ALL on its own db; SELECT on ladill_merchant + ladilldb for commerce links)
  2. /var/www/ladill-pos/{releases,shared} owned deploy:www-data
  3. shared/.env (mode 640, deploy:www-data) with generated APP_KEY, DB creds, and the integration keys from the monolith (see "Platform wiring")
  4. nginx vhost via deployment/setup-service-subdomain-nginx.sh pos --app /var/www/ladill-pos/current
php artisan migrate --force
php artisan config:cache && php artisan route:cache && php artisan view:cache
  • CRMCRM_API_KEY_POS on CRM + CRM_API_URL / CRM_API_KEY_POS on POS; timeline on paid sales; product import from CRM API
  • Invoice — "Create invoice" on paid sale receipt (kind: pos_sale prefill)
  • MerchantMERCHANT_DB_* read-only connection; import storefront catalog into pos_products