Files
ladill-hosting/DEPLOY.md
T
isaaccladandCursor 2df303048c
Deploy Ladill Hosting / deploy (push) Successful in 21s
Fix CI deploy: sync composer.lock and add hosting config.
phpseclib was missing from the lock file, which caused composer install
to fail on the Gitea deploy runner.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 16:31:44 +00:00

4.2 KiB

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

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)

# 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:

BILLING_API_KEY_HOSTING=<same as this app>
IDENTITY_API_KEY_HOSTING=<same as this app>
RP_HOSTING_FRONTCHANNEL_LOGOUT=https://hosting.ladill.com/sso/logout-frontchannel
LADILL_HOSTING_APP_URL=https://hosting.ladill.com

Then php artisan config:cache on the platform.

5. nginx + TLS

sudo deployment/setup-service-subdomain-nginx.sh hosting --app ladill-hosting

DNS hosting.ladill.com is already in config/pdns.phpdns:sync-subdomains on deploy.

6. First deploy

Push to main (CI) or run deploy manually, then:

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

# 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.