Deploy Ladill POS / deploy (push) Successful in 24s
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>
62 lines
3.1 KiB
Markdown
62 lines
3.1 KiB
Markdown
# 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`
|
|
|
|
```bash
|
|
php artisan migrate --force
|
|
php artisan config:cache && php artisan route:cache && php artisan view:cache
|
|
```
|
|
|
|
## Commerce links
|
|
|
|
- **CRM** — `CRM_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)
|
|
- **Merchant** — `MERCHANT_DB_*` read-only connection; import storefront catalog into `pos_products`
|