Wire admin studio SSR and search infrastructure
This commit is contained in:
@@ -15,17 +15,21 @@ If you launch `bash sync.sh` from WSL against this Windows checkout, the script
|
||||
This will:
|
||||
|
||||
- build frontend assets locally with `npm run build`
|
||||
- rsync the application files to production
|
||||
- run `composer install --no-dev` on the server before entering maintenance mode
|
||||
- bring the app down only for the short critical section that runs `php artisan migrate --force`, `php artisan optimize:clear`, and `php artisan optimize`
|
||||
- stage the new code into a versioned release directory on the production server
|
||||
- run `composer install --no-dev` inside that staged release before switching traffic
|
||||
- keep the fixed production app path pointed at the active release through a server-side `current` symlink
|
||||
- bring the app down only for the short critical section that switches the active release and runs `php artisan migrate --force`, `php artisan optimize:clear`, and `php artisan optimize`
|
||||
- bring the app back up immediately after that critical section finishes
|
||||
- warm the guest homepage cache with `php artisan homepage:warm-guest-cache`
|
||||
- warm the post trending cache with `php artisan posts:warm-trending`
|
||||
- restart queue workers with `php artisan queue:restart`
|
||||
- gracefully restart Horizon with `php artisan horizon:terminate`
|
||||
|
||||
This is now the low-downtime default path for normal code and feature deploys.
|
||||
|
||||
Each deploy generates a release ID automatically from UTC time and the local Git revision. Releases are retained under `REMOTE_RELEASE_ROOT/releases/<release-id>`, and production switches between them on the server by updating `REMOTE_RELEASE_ROOT/current`. The public/runtime path stays fixed at `REMOTE_FOLDER`, which is now treated as a stable symlink to the active release.
|
||||
|
||||
On the first deploy with this layout, the existing live folder is adopted into the release archive automatically and `REMOTE_FOLDER` is converted into that stable symlink path. After that, switching back to an older release does not require any local re-upload.
|
||||
|
||||
## Full upgrade
|
||||
|
||||
Use a full upgrade when the release also needs broad Meilisearch work or non-code service operations.
|
||||
@@ -63,12 +67,15 @@ bash sync.sh --skip-build
|
||||
bash sync.sh --skip-migrate
|
||||
bash sync.sh --no-maintenance
|
||||
bash sync.sh --mode=full-upgrade
|
||||
bash sync.sh --keep-releases=8
|
||||
bash sync.sh --release-id=release-2026-04-25
|
||||
```
|
||||
|
||||
Environment overrides:
|
||||
|
||||
```bash
|
||||
REMOTE_SERVER=user@example.com REMOTE_FOLDER=/var/www/app bash sync.sh
|
||||
REMOTE_RELEASE_ROOT=/var/www/app.releases RELEASE_RETENTION=8 bash sync.sh
|
||||
```
|
||||
|
||||
You can also override the local build command explicitly:
|
||||
@@ -85,6 +92,40 @@ FULL_UPGRADE_PRE_HOOK='sudo systemctl stop reverb' bash sync.sh --full-upgrade
|
||||
FULL_UPGRADE_POST_HOOK='sudo systemctl restart reverb meilisearch' bash sync.sh --full-upgrade
|
||||
```
|
||||
|
||||
## Rollback and release history
|
||||
|
||||
List retained releases on production:
|
||||
|
||||
```bash
|
||||
bash scripts/rollback-production.sh --list
|
||||
```
|
||||
|
||||
Switch production to the previous retained release:
|
||||
|
||||
```bash
|
||||
bash scripts/rollback-production.sh --previous
|
||||
```
|
||||
|
||||
Switch production to a specific retained release:
|
||||
|
||||
```bash
|
||||
bash scripts/rollback-production.sh --release-id=20260425-132455-a1b2c3d
|
||||
```
|
||||
|
||||
Preview a release switch without changing the server:
|
||||
|
||||
```bash
|
||||
bash scripts/rollback-production.sh --previous --dry-run
|
||||
```
|
||||
|
||||
Operational notes:
|
||||
|
||||
- Rollback now means switching the active server release, not re-syncing files from local.
|
||||
- Each retained release already contains its own code and vendor tree, so rollback is primarily a symlink switch plus cache refresh and `queue:restart`.
|
||||
- Rollback does not reverse database migrations. If a release includes incompatible schema changes, handle the database separately.
|
||||
- Release retention defaults to 5 releases and can be changed with `--keep-releases` or `RELEASE_RETENTION`.
|
||||
- Release data lives outside the active app path by default at `REMOTE_FOLDER.releases`, so switching releases happens entirely on the production server.
|
||||
|
||||
## Replace production database from local
|
||||
|
||||
This is intentionally separate from a normal deploy because it overwrites production data.
|
||||
@@ -139,4 +180,24 @@ LOCAL_MYSQLDUMP_COMMAND='mysqldump --host=10.0.0.5 --port=3306 --user=app dbname
|
||||
- Normal deployments should use `bash sync.sh` without `--with-db`.
|
||||
- Use `bash sync.sh --full-upgrade` only when the release also includes Meilisearch-wide refreshes or remote service changes.
|
||||
- Use database replacement only for first-time bootstrap, staging, or an intentional full production reset.
|
||||
- Route caching now runs through `php artisan optimize` in deploy automation; if that starts failing again, fix the route definitions instead of dropping route caching from deploy.
|
||||
- Use `bash scripts/rollback-production.sh --previous` for a fast server-side release switch when the last deploy needs to be reverted.
|
||||
- Route caching now runs through `php artisan optimize` in deploy automation; if that starts failing again, fix the route definitions instead of dropping route caching from deploy.
|
||||
|
||||
## Nginx upstream error pages
|
||||
|
||||
Laravel now owns the Nova-style HTML error pages for normal application responses, but true upstream failures such as `502 Bad Gateway` and `504 Gateway Timeout` still have to be handled by nginx because PHP/FPM is unavailable in that state.
|
||||
|
||||
The repo includes a ready-to-include snippet at `deploy/nginx/upstream-error-pages.conf` and the matching static page at `public/errors/upstream-gateway.html`.
|
||||
|
||||
To enable it on production:
|
||||
|
||||
1. Include the snippet inside the Skinbase `server {}` block.
|
||||
2. Add `fastcgi_intercept_errors on;` to every FastCGI location that should use the static fallback.
|
||||
3. Keep the static file available in the live public path so nginx can serve it without Laravel.
|
||||
|
||||
On the current `skinbase.top` vhost, the required FastCGI locations are:
|
||||
|
||||
- `location ^~ /api/uploads/`
|
||||
- `location = /index.php`
|
||||
|
||||
This intentionally intercepts only `502` and `504`, so Laravel remains responsible for normal `404`, `419`, `429`, `500`, and `503` rendering when the application is actually running.
|
||||
Reference in New Issue
Block a user