# Hosted Deployment Spec — Commercial Pilot 1.0.0-pilot

Single-tenant GDP Portal deployment on cPanel shared hosting or a small VPS.

## Model

- **One customer organisation per installation** — identified by `installations.installation_id` and `organisation_settings`.
- **Not multi-tenant SaaS** — each deploy gets its own database, file storage, and config.
- **Not MHRA-approved** — the portal supports GDP operations; it does not certify compliance.

## Minimum stack

| Component | Requirement |
|-----------|-------------|
| PHP | 8.1+ with PDO MySQL, fileinfo, json, mbstring, openssl |
| MySQL / MariaDB | 8.0+ or MariaDB 10.6+ (utf8mb4) |
| Web server | Apache (mod_rewrite) or nginx → `public/` docroot |
| Disk | DB + `storage/private/` evidence (plan 5–50 GB depending on retention) |

## Directory layout (production)

```
/var/www/gdp-portal/
  public/              ← web docroot only
  app/                 ← blocked by .htaccess / nginx deny
  storage/private/     ← evidence files (0750, not web-served)
  uploads/             ← legacy path; migrate to private where possible
  migrations/
  scripts/
  install.lock         ← after successful install
```

## Install sequence

1. Upload release tarball; verify `MANIFEST.sha256` / `scripts/verify_release.sh`.
2. Create empty MySQL database and user (least privilege: SELECT/INSERT/UPDATE/DELETE on that DB only).
3. Copy `app/config.php.example` → `app/config.php` (or run web installer once).
4. Set `app.url` to production HTTPS URL; set `app.env` to `production`.
5. Run installer OR import `install.sql` then `scripts/run_migrations.php`.
6. Configure **Organisation Settings** (`/organisation-config`) — legal name, portal title, WDA number.
7. Change default admin password; enrol MFA for RP/admin roles.
8. Create `install.lock`; remove or restrict public access to installer.
9. Schedule `scripts/backup_full.sh` (database + evidence) via cron.

## cPanel notes

- Point subdomain docroot to `public/`.
- PHP version selector → 8.1+; enable `fileinfo`.
- Cron: `0 2 * * * /bin/bash /home/user/gdp-portal/scripts/backup_full.sh`
- `storage/private` must be outside `public_html` or denied by server rules.

## VPS notes

- Run PHP-FPM behind nginx; TLS via Let's Encrypt.
- MySQL on localhost or managed RDS; firewall DB port.
- Separate OS user for PHP; ownership `www-data:www-data` on writable dirs only.
- Off-site backup of DB dumps + evidence tarballs (S3, rsync, etc.).

## Post-deploy verification

- `/system-health` — no unexpected GDP Integrity failures.
- `scripts/prove_restore.sh` on staging clone.
- `EVIDENCE_CHECK=1 scripts/prove_restore.sh` after evidence restore test.
- Login smoke test + one GRN / dispatch / SOP workflow.

## Demo environments

Set `app.env` = `demo` or `app.demo_mode` = true. A banner is shown; do not use demo installs for regulated production data.
