feat(isac): link skill chips to abilities
This commit is contained in:
+40
-44
@@ -1,9 +1,9 @@
|
||||
# Container, staging, and production deployment
|
||||
|
||||
SHD.build is packaged as a Node 24 container using the official SvelteKit Node
|
||||
adapter. The image contains application code, migration and notification
|
||||
scripts, and native runtime dependencies. It does not contain an environment
|
||||
file, database, backups, or user uploads.
|
||||
SHD.build runs in a Node 24 container through the official SvelteKit Node
|
||||
adapter. The image includes application code, migration and notification
|
||||
scripts, and native runtime dependencies. Environment files, databases,
|
||||
backups, and user uploads remain outside the image.
|
||||
|
||||
## Persistent data
|
||||
|
||||
@@ -15,10 +15,9 @@ mounted at `/app/data`. It contains:
|
||||
- normalized user avatars under `avatars/`;
|
||||
- uploaded game-data icons under `game-icons/`.
|
||||
|
||||
Never remove this volume during routine deployments. `docker compose down`
|
||||
without `--volumes` preserves it. Before any manual backup or restore, stop
|
||||
both the `app` and `scheduler` services because both access the embedded
|
||||
database.
|
||||
Keep this volume during routine deployments. `docker compose down` without
|
||||
`--volumes` preserves it. Before a manual backup or restore, stop the `app`
|
||||
and `scheduler` services because both access the embedded database.
|
||||
|
||||
## Staging environment
|
||||
|
||||
@@ -46,9 +45,9 @@ port on the host interfaces so a containerized reverse proxy or tunnel can
|
||||
reach it; firewall the port to trusted LAN/tunnel sources when the host is
|
||||
reachable from other networks.
|
||||
|
||||
The deployment decrypts `.env.staging` on the trusted staging runner into a
|
||||
mode-`0600` runtime file. The decryption key is held by Gitea Actions, not
|
||||
committed or included in the container image.
|
||||
The trusted staging runner decrypts `.env.staging` into a mode-`0600` runtime
|
||||
file. Gitea Actions holds the decryption key; Git and the container image do
|
||||
not.
|
||||
|
||||
The staging container disables default-user seeding. On a brand-new staging
|
||||
database, the existing bootstrap policy grants Admin to the first real account
|
||||
@@ -93,9 +92,9 @@ In `https://git.jb.codes/jb/shd.build/settings/actions`:
|
||||
3. Optionally add repository variable `STAGE_PORT`. It defaults to `5569`.
|
||||
4. Ensure Actions are enabled and the `stage-deploy` runner is online.
|
||||
|
||||
The workflow at `.gitea/workflows/deploy-staging.yml` runs on every push to
|
||||
`main` and can also be started manually. It does not need registry credentials
|
||||
because the trusted staging runner builds a commit-tagged image locally.
|
||||
`.gitea/workflows/deploy-staging.yml` runs for pushes to `main` and manual
|
||||
dispatches. The trusted staging runner builds each commit-tagged image locally,
|
||||
so the workflow needs no registry credentials.
|
||||
|
||||
## Deployment lifecycle
|
||||
|
||||
@@ -110,8 +109,7 @@ The workflow:
|
||||
7. waits for `/api/health/database` to report healthy;
|
||||
8. retains the logs and exits unsuccessfully if health verification fails.
|
||||
|
||||
The short outage is limited to backup, migration, and container startup. This
|
||||
follows the database-preservation policy while minimizing data-entry downtime.
|
||||
The outage covers backup, migration, and container startup.
|
||||
The scheduler calls a bearer-authenticated endpoint on the application service
|
||||
once per minute. Scheduled message delivery therefore uses the web process's
|
||||
existing embedded-database connection instead of opening the locked database
|
||||
@@ -120,11 +118,10 @@ consolidation, and email digest checks and is not published through a host port.
|
||||
|
||||
## Initial development-data bootstrap
|
||||
|
||||
The first staging release can be initialized from the current development
|
||||
database, including users, roles, builds, guides, proposals, audit history,
|
||||
avatars, and uploaded game-data icons. This is deliberately a one-time flow:
|
||||
the staging importer refuses to run after users, builds, audits, or proposals
|
||||
exist in its target database.
|
||||
Initialize the first staging release from the development database, including
|
||||
users, roles, builds, guides, proposals, audit history, avatars, and uploaded
|
||||
game-data icons. The staging importer refuses a target database that contains
|
||||
users, builds, audits, or proposals.
|
||||
|
||||
First stop this project's development server. The embedded database must not be
|
||||
open while its complete transfer bundle is created:
|
||||
@@ -134,8 +131,8 @@ npm run stage:bootstrap:export
|
||||
```
|
||||
|
||||
The command writes a timestamped, ignored JSON bundle under `data/backups/`.
|
||||
It contains user records and password hashes, so transfer it over an encrypted
|
||||
channel and never add it to Git. Copy it to the staging host, then run:
|
||||
The bundle includes user records and password hashes. Transfer it over an
|
||||
encrypted channel, keep it out of Git, then copy it to the staging host and run:
|
||||
|
||||
```sh
|
||||
/opt/shd-build-stage/bootstrap-staging.sh \
|
||||
@@ -160,8 +157,8 @@ Actions. It briefly stops staging database writers, exports only canonical
|
||||
builder-source tables plus uploaded game-data icons, restarts staging, and
|
||||
publishes a `shd-stage-isac-data` artifact for 14 days.
|
||||
|
||||
Download `isac-stage.json` from that workflow run. Then stop this project's
|
||||
development server and run:
|
||||
Download `isac-stage.json` from that workflow run, stop this project's
|
||||
development server, and run:
|
||||
|
||||
```sh
|
||||
npm run isac:import -- /path/to/isac-stage.json --confirm-replace-isac-data
|
||||
@@ -206,10 +203,10 @@ environment, port, and deployment workflow:
|
||||
- Database: `/app/data/shd-build-production.db`
|
||||
- Persistent volume: `shd-build-production-data`
|
||||
|
||||
Routine pushes never import or replace production data. The production deploy
|
||||
stops only its application and scheduler, creates a timestamped JSON backup,
|
||||
applies repeatable migrations, restarts, and verifies database health. Never
|
||||
run `docker compose down --volumes` against production.
|
||||
Routine pushes leave production data unchanged. The production deploy stops its
|
||||
application and scheduler, creates a timestamped JSON backup, applies repeatable
|
||||
migrations, restarts, and verifies database health. Keep
|
||||
`docker compose down --volumes` away from production.
|
||||
|
||||
Add these repository Action secrets:
|
||||
|
||||
@@ -234,8 +231,8 @@ reuse the staging scheduler token.
|
||||
|
||||
### Initial production bootstrap
|
||||
|
||||
The one-time production bootstrap clones current development data and uploads.
|
||||
Stop this project's development server before creating the bundle:
|
||||
The production bootstrap clones current development data and uploads. Stop this
|
||||
project's development server before creating the bundle:
|
||||
|
||||
```sh
|
||||
npm run production:bootstrap:export
|
||||
@@ -269,9 +266,8 @@ notifications, settings, and audit history untouched.
|
||||
|
||||
Manually run **Replace staging ISAC data from production** in Gitea Actions.
|
||||
The workflow exports a consistent production snapshot, restarts production,
|
||||
then stops staging and imports it. The staging importer creates both full and
|
||||
ISAC-only safety backups before replacement. This is intentionally manual and
|
||||
never runs as part of either deployment.
|
||||
then stops staging and imports it. The staging importer creates full and
|
||||
ISAC-only safety backups before replacement. Deployments do not run this flow.
|
||||
|
||||
### Promote managed images without replacing other data
|
||||
|
||||
@@ -280,9 +276,9 @@ development. Export a bundle after finishing local uploads and metadata edits:
|
||||
|
||||
Set the server-only `REMOVE_BG_API_KEY` in each encrypted environment that
|
||||
accepts ISAC uploads. It is sent only from the server in the `X-Api-Key` header.
|
||||
Icon uploads that already contain transparency do not call remove.bg; opaque
|
||||
icon sources use its preview output and then continue through local trimming,
|
||||
white normalization, WebP conversion, and storage.
|
||||
Transparent icon uploads skip remove.bg. Opaque sources use its preview output,
|
||||
then pass through local trimming, white normalization, WebP conversion, and
|
||||
storage.
|
||||
|
||||
```sh
|
||||
npm run images:export
|
||||
@@ -311,13 +307,13 @@ docker compose -f compose.production.yml run --rm \
|
||||
docker compose -f compose.production.yml up -d app scheduler
|
||||
```
|
||||
|
||||
Each import creates a full target database backup before changing anything.
|
||||
New stable IDs are inserted, identical existing assets are skipped, and a
|
||||
different existing record blocks the import. After reviewing an intentional
|
||||
metadata or file replacement, add `--update-existing`. Imported changes append
|
||||
`image.imported` or `image.import_updated` audit events. Remove the transferred
|
||||
bundle after both environments have been verified because it may contain
|
||||
unpublished visual assets and creator identifiers.
|
||||
Each import creates a full target database backup before changes. The importer
|
||||
adds new stable IDs, skips identical assets, and blocks conflicting records.
|
||||
After reviewing an intentional metadata or file replacement, add
|
||||
`--update-existing`. Imported changes append `image.imported` or
|
||||
`image.import_updated` audit events. Remove the transferred bundle after
|
||||
verifying both environments because it may contain unpublished visual assets
|
||||
and creator identifiers.
|
||||
|
||||
The `.env.staging` and `.env.production` npm import commands are intended for
|
||||
maintenance performed directly in an environment where those database and
|
||||
|
||||
Reference in New Issue
Block a user