Add deployment hardening scripts

This commit is contained in:
Codex
2026-07-10 18:44:13 -05:00
parent de9e473d3b
commit 9f58940b84
10 changed files with 478 additions and 16 deletions
+145
View File
@@ -35,6 +35,10 @@ This document records the explicit runtime requirements and server changes for P
- `TSE_ATTACHMENT_ROOT`, default `attachments`.
- `TSE_ATTACHMENT_MAX_KB`, default `10240`.
- `TSE_ATTACHMENT_MIME_TYPES`, comma-separated allowlist.
- Backup policy environment variables:
- `TSE_BACKUP_DIR`, optional backup destination override.
- `TSE_BACKUP_STORAGE`, default `1`, controls whether `storage/app` is archived with the database.
- `TSE_BACKUP_BEFORE_UPDATE`, default `0`, runs `scripts/backup.sh` before `scripts/update.sh` when set to `1`.
## Local Test Requirements
@@ -53,6 +57,147 @@ This document records the explicit runtime requirements and server changes for P
- Cron entry for `php artisan schedule:run`.
- Shared/object storage before multi-server deployment.
## Queue Worker
The current ChristIT test deployment uses the database queue driver. That is acceptable for low-volume testing, but real notification, email, import, and image-processing work should run under a persistent worker.
Example systemd unit:
```ini
[Unit]
Description=Provider Exchange queue worker
After=network.target
[Service]
User=www-data
Group=www-data
Restart=always
WorkingDirectory=/sites/provider-exchange
ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600
[Install]
WantedBy=multi-user.target
```
Reload workers after deployment with:
```bash
php artisan queue:restart
```
## Scheduler
Laravel's scheduler should be invoked once per minute by cron:
```cron
* * * * * cd /sites/provider-exchange && /usr/bin/php artisan schedule:run >> /dev/null 2>&1
```
## PHP-FPM
Keep the app behind a dedicated PHP-FPM pool when production traffic increases. The pool should have:
- Its own Unix socket.
- A deploy user/group that can read the app and write `storage/` and `bootstrap/cache/`.
- `pm.max_children`, `pm.start_servers`, and spare server counts sized from observed memory usage.
- `request_terminate_timeout` high enough for uploads, but not high enough to pin workers indefinitely.
- `upload_max_filesize` and `post_max_size` aligned with `TSE_ATTACHMENT_MAX_KB`.
Do not change unrelated PHP-FPM sockets used by existing ChristIT sites when tuning this app.
## Redis Migration Plan
Before running multiple web nodes or high-volume alerting, move transient state out of the database:
```env
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
```
After changing these values, run:
```bash
php artisan optimize:clear
php artisan queue:restart
```
Database-backed notifications can stay in the database because they are user-visible records. Queue transport, sessions, and cache should move first.
## Backups
Run an on-demand backup from the app directory:
```bash
bash scripts/backup.sh
```
The script supports SQLite, MySQL/MariaDB, and PostgreSQL based on `.env`. It writes a manifest beside the database backup. By default it also archives `storage/app`.
Run an update with a preflight backup:
```bash
TSE_BACKUP_BEFORE_UPDATE=1 bash scripts/update.sh
```
Recommended production posture:
- Store backups outside the app directory with `TSE_BACKUP_DIR`.
- Replicate backups off-server.
- Test restore steps before relying on the backup plan.
- Keep evidence attachments and profile uploads under a retention policy that matches the platform's dispute and audit needs.
## Health Check
Run:
```bash
bash scripts/health-check.sh
```
The check verifies Laravel boot, database/migration reachability, API and notification routes, writable cache/storage directories, storage symlink, and built Vite assets.
## Log Rotation
Laravel writes logs under `storage/logs`. Add a logrotate rule before real traffic:
```conf
/sites/provider-exchange/storage/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data www-data
}
```
## Storage Scaling
Local public storage is acceptable for the first ChristIT test deployment. Before multi-server deployment:
- Move uploads/evidence to shared or object storage.
- Keep private evidence behind controller authorization instead of direct public URLs.
- Add malware scanning for uploaded evidence.
- Add thumbnail generation for large images.
- Add quota policy by user and work order.
- Keep attachment disk/path metadata stable so old evidence records continue to resolve after storage migration.
## Database Scaling
Phase 14A added indexes for high-use filters and timelines: jobs, profiles, quotes, work orders, messages, reviews, ratings, disputes, attachments, external imports, and notifications.
Next database reliability steps after real usage begins:
- Add cached reputation aggregates based on measured slow pages.
- Add query monitoring.
- Move from SQLite to MariaDB/MySQL or PostgreSQL before treating data as production-critical.
- Keep migrations additive where possible and back up before every schema-changing deployment.
## ChristIT Test Deployment
Target URL: