Deploy Ladill Hosting / deploy (push) Successful in 1m29s
Expose authenticated service endpoints for assigning, listing, renewing, and managing hosting accounts from the platform, with tests and deploy docs. Co-authored-by: Cursor <cursoragent@cursor.com>
132 lines
4.4 KiB
Markdown
132 lines
4.4 KiB
Markdown
# Ladill Hosting — deploy & cutover runbook
|
|
|
|
Standalone app for **shared web hosting** at `hosting.ladill.com` (single-domain,
|
|
multi-domain, WordPress). **VPS and dedicated servers** are a separate product —
|
|
**Ladill Servers** at `servers.ladill.com` (not part of this app).
|
|
It trusts `auth.ladill.com` for login (OIDC) and bills the one platform
|
|
UserWallet over the §4-A Billing API. Provisioning runs against Contabo nodes
|
|
and the shared hosting infrastructure (same stack as the monolith phase).
|
|
|
|
Mirrors the Ladill Domains / Email deployment model (app-slot + own DB + Gitea CI).
|
|
|
|
---
|
|
|
|
## 0. Prerequisites
|
|
|
|
| Secret | Where it comes from |
|
|
|---|---|
|
|
| `CONTABO_CLIENT_ID` / `CONTABO_CLIENT_SECRET` / `CONTABO_API_USER` / `CONTABO_API_PASSWORD` | Contabo API credentials |
|
|
| `PDNS_API_URL` / `PDNS_API_KEY` | PowerDNS (zone management) |
|
|
| `PAYSTACK_SECRET_KEY` / `PAYSTACK_PUBLIC_KEY` | Paystack dashboard |
|
|
| `LADILL_SSO_CLIENT_ID` / `LADILL_SSO_CLIENT_SECRET` | step 3 |
|
|
| `BILLING_API_KEY_HOSTING` | step 4 (must match platform env) |
|
|
| `IDENTITY_API_KEY_HOSTING` | step 4 (must match platform env) |
|
|
|
|
---
|
|
|
|
## 1. Gitea repo + CI
|
|
|
|
1. Repo: **http://161.97.138.149:3000/isaacclad/ladill-hosting**
|
|
2. Push to `main` triggers `.gitea/workflows/deploy.yml` on the **deploy** runner
|
|
(`ladill-deploy-runner.service` on the VPS — same as Bird/Domains/Email).
|
|
3. Pipeline: clone → `npm ci && npm run build` → release tarball →
|
|
`deploy/deploy.sh` → `/var/www/ladill-hosting/current`.
|
|
4. No SSH secrets required — the runner executes on-host as `deploy`.
|
|
5. Manual deploy: Gitea → Actions → **Deploy Ladill Hosting** → Run workflow.
|
|
|
|
## 2. Server app-slot + database
|
|
|
|
```bash
|
|
sudo install -d -o deploy -g www-data /var/www/ladill-hosting
|
|
|
|
sudo mysql -e "CREATE DATABASE ladill_hosting CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
|
sudo mysql -e "CREATE USER 'ladill_hosting'@'127.0.0.1' IDENTIFIED BY '<pw>';"
|
|
sudo mysql -e "GRANT ALL ON ladill_hosting.* TO 'ladill_hosting'@'127.0.0.1'; FLUSH PRIVILEGES;"
|
|
```
|
|
|
|
Create `/var/www/ladill-hosting/.env` from `.env.example`, fill secrets,
|
|
then `php artisan key:generate`.
|
|
|
|
## 3. Register the OIDC client (platform / auth.ladill.com)
|
|
|
|
```bash
|
|
# On the monolith
|
|
php artisan passport:client \
|
|
--name="Ladill Hosting" \
|
|
--redirect_uri="https://hosting.ladill.com/sso/callback"
|
|
```
|
|
|
|
Set `LADILL_SSO_CLIENT_ID` / `LADILL_SSO_CLIENT_SECRET` in this app's `.env`.
|
|
|
|
## 4. Platform integration
|
|
|
|
On the **platform** `.env`:
|
|
|
|
```env
|
|
BILLING_API_KEY_HOSTING=<same as this app>
|
|
IDENTITY_API_KEY_HOSTING=<same as this app>
|
|
HOSTING_API_KEY_ACCOUNT=<same as PLATFORM_API_KEY_HOSTING below>
|
|
RP_HOSTING_FRONTCHANNEL_LOGOUT=https://hosting.ladill.com/sso/logout-frontchannel
|
|
LADILL_HOSTING_APP_URL=https://hosting.ladill.com
|
|
```
|
|
|
|
On this app's `.env`:
|
|
|
|
```env
|
|
PLATFORM_API_KEY_HOSTING=<same as platform HOSTING_API_KEY_ACCOUNT>
|
|
```
|
|
|
|
Then `php artisan config:cache` on the platform.
|
|
|
|
## 5. nginx + TLS
|
|
|
|
```bash
|
|
sudo deployment/setup-service-subdomain-nginx.sh hosting --app ladill-hosting
|
|
```
|
|
|
|
DNS `hosting.ladill.com` is already in `config/pdns.php` → `dns:sync-subdomains` on deploy.
|
|
|
|
## 6. First deploy
|
|
|
|
Push to `main` (CI) or run deploy manually, then:
|
|
|
|
```bash
|
|
cd /var/www/ladill-hosting/current
|
|
php artisan migrate --force
|
|
php artisan db:seed --class=HostingProductSeeder --force
|
|
php artisan config:cache route:cache view:cache
|
|
chgrp -R www-data storage bootstrap/cache && chmod -R g+rwX storage bootstrap/cache
|
|
```
|
|
|
|
Ensure a queue worker runs (`queue:work` via supervisor).
|
|
|
|
## 7. Zero-loss migration
|
|
|
|
```bash
|
|
# a) On the platform — export customer hosting rows
|
|
php artisan hosting:export --out=/tmp/hosting-export.json
|
|
|
|
# b) Copy to the hosting app server, dry-run import
|
|
php artisan hosting:import /tmp/hosting-export.json
|
|
|
|
# c) Apply
|
|
php artisan hosting:import /tmp/hosting-export.json --commit
|
|
```
|
|
|
|
Re-running import is idempotent (upserts by original platform id).
|
|
|
|
## 8. Smoke test
|
|
|
|
- `https://hosting.ladill.com/up` → 200
|
|
- Logged-out → SSO redirect to auth.ladill.com
|
|
- Logged-in → dashboard lists imported accounts
|
|
- Open an account → panel loads (files, domains, SSL)
|
|
- Buy a test shared hosting plan end-to-end (wallet)
|
|
- Log out → SLO clears hosting session
|
|
|
|
## 9. Decommission platform hosting UI (after burn-in)
|
|
|
|
Account sidebar + `/hosting/*` on account.ladill.com already redirect to
|
|
`hosting.ladill.com`. After burn-in, remove remaining platform hosting models/jobs
|
|
once the hosting app is the sole writer.
|