88 lines
3.5 KiB
Markdown
88 lines
3.5 KiB
Markdown
# Contabo release operations
|
||
|
||
This site publishes static content through the merged Contabo release manager.
|
||
It does not run `nixos-rebuild`, reload nginx, change DNS, or write directly to
|
||
`/srv/www/azinstitute4autism.com/www/dist`.
|
||
|
||
## Required local tools and private inputs
|
||
|
||
- Node.js 22+, Git, tar, SSH and rsync.
|
||
- A normal SSH identity accepted by the existing root receiver:
|
||
`AIA_DEPLOY_SSH_IDENTITY=/absolute/path/to/identity`.
|
||
- `AIA_DEPLOY_HOST=administrator@host` (or the approved equivalent).
|
||
- For a real public release, an owner-controlled, regular encrypted payload:
|
||
`AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json`.
|
||
|
||
The payload remains outside Git and the source snapshot. It is browser ciphertext
|
||
only; neither access code nor decrypted portal HTML enters an Astro environment
|
||
variable, public resource directory, build log, or deployment manifest.
|
||
|
||
## Commands
|
||
|
||
From `www/`:
|
||
|
||
```sh
|
||
npm run deploy -- --dry-run
|
||
```
|
||
|
||
Dry-run performs the local production build, tests, artifact verification,
|
||
manifest creation and source-snapshot preparation. With no private production
|
||
payload it uses a generated synthetic two-stream fixture and explicitly reports
|
||
that the result is not production-ready. It never opens SSH or rsync.
|
||
|
||
```sh
|
||
AIA_DEPLOY_HOST='root@approved-host' \
|
||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||
AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE="$PWD/private/employee-portal/approved-production-ciphertext.json" \
|
||
npm run deploy -- --confirm
|
||
```
|
||
|
||
The confirmed command builds with `PUBLIC_ALLOW_INDEXING=true`, Form A live and
|
||
counters off, then uploads only fresh commit-specific `staging/source-<sha>` and
|
||
`staging/dist-<sha>` directories. It runs, in order:
|
||
|
||
```text
|
||
aia-website-release verify
|
||
aia-website-release sync-source
|
||
aia-website-release promote
|
||
```
|
||
|
||
The VPS verifies the manifest, promotes an immutable release by atomic symlink,
|
||
and retains the prior release. A successful rsync transfer alone is not success.
|
||
|
||
Rollback requires the reviewed manifest retained at the server’s fixed path:
|
||
|
||
```sh
|
||
AIA_DEPLOY_HOST='root@approved-host' \
|
||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||
npm run deploy:rollback -- FULL_APPROVED_SHA --confirm
|
||
```
|
||
|
||
## Employee resources: separate one-time operation
|
||
|
||
Approved non-PHI employee files are never part of an ordinary release. After
|
||
the website release that contains `portal-resource-install.mjs` is promoted and
|
||
the VPS SOPS-backed Basic Auth material is independently ready:
|
||
|
||
```sh
|
||
npm run deploy:portal-resources -- --dry-run
|
||
|
||
AIA_DEPLOY_HOST='root@approved-host' \
|
||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||
npm run deploy:portal-resources -- --confirm
|
||
```
|
||
|
||
The installer reads only the private collection manifest, accepts approved
|
||
`STAFF-INTERNAL` and `MANAGEMENT-INTERNAL` mappings to `/staff-resources/` and
|
||
`/management-resources/`, verifies every local hash, rejects links/traversal and
|
||
uploads a root-controlled temporary tree. It never uses `--delete` for resource
|
||
directories and refuses to replace a different existing file. The VPS installs
|
||
regular files as `root:nginx` mode `0640` and reports metadata only.
|
||
|
||
Before public DNS cutover, test the site with approved host-header/SNI methods,
|
||
including the portal’s noindex response, valid ciphertext unlock, both protected
|
||
resource namespaces, denial cases, redirects, Form A, IPv4 and IPv6. Portal
|
||
shared-code rotation is coordinated: update VPS SOPS inputs and privately
|
||
re-encrypt the browser payload together. This interim portal is non-PHI and is
|
||
not an employee identity system.
|