The 2dc9ad2 commit ("refactor: distribute via Codeberg release assets,
drop the upstream image") rewrote AGENTS.md and CLAUDE.md but left
several pre-existing references to the old write-to-website/releases
flow and the now-removed Containerfile / podman-compose / release-image.sh.
This sweeps the rest:
- CLAUDE.md
- drop "podman/podman-compose" from the zddc/ blurb (no Containerfile)
- drop the broken `podman build -t zddc-server zddc/` command
- rewrite the "Most-used commands" table so --release semantics match
actual behavior (tag + Codeberg upload, not file write)
- rewrite "Things that bite": replace "never write to website/releases/"
and the obsolete "alpha exception" bullet with the new rules
($CODEBERG_TOKEN required, dist files no longer force-tracked, etc.)
- rewrite the website/ description in "Repo shape" to reflect that
only index.html + manifest.json live there now
- ARCHITECTURE.md
- rewrite the website/ directory tree (no more <tool>_v*.html, _stable
symlinks, or _alpha/_beta files)
- rewrite "Channels" section: every cut now tags + uploads to Codeberg,
alpha/beta have .N counters and matching tags, no more in-place
overwrites
- rewrite the build-label table: dev builds carry the next-stable
target as a -alpha pre-release suffix with full timestamp + dirty
marker (was: "Built: <ts> BETA")
- update level-2 bootstrap description: resolves channel via
manifest.json, fetches /releases/<tag>/<asset>, not a flat URL
- update landing-tool description: ships only as Codeberg release
asset, not a committed website/releases/landing_v<X>.html
- AGENTS.md
- update website/ tree to the post-refactor layout
- replace the two-step podman build / podman-compose run blocks under
zddc-server with a Go build + go run quickstart (no container in
this repo)
- drop the "Containerfile uses a multi-stage build" note from the
"Notes" list (Containerfile is gone)
- drop the stale "landing/build.sh writes website/index.html" note —
website/index.html is now hand-edited, not produced by landing's
build
- README.md (top-level)
- tools table no longer links to /releases/<tool>_stable.html
(those URLs return 404 post-refactor); link to the releases page
once instead
- bootstrap/README.md
- update the "permanent pin" URL examples and CORS verification
snippet to use /releases/<tag>/<asset> URLs (Caddy → Codeberg)
instead of the old flat /releases/<tool>_<channel>.html pattern
- explain that channel resolution is via manifest.json now
- zddc/README.md
- rewrite Quick Start: download a release binary or build from source,
no `podman build`
- rewrite TLS examples to invoke ./zddc-server directly instead of
`podman run ... zddc-server` (image name no longer exists)
- mention ZDDC_INSECURE_DIRECT in the env-var table and the plain-HTTP
example — startup is refused without it on non-loopback binds
- replace the "Container image" section with "Distribution" (binaries
on Codeberg, no image) and the "Building" section with go build
instructions
- replace "Release Tagging" with documentation of zddc/release.sh
(the canonical replacement for release-image.sh, which is gone)
- shared/build-lib.sh
- fix the comment claiming "plain builds mirror to website/releases/"
— they don't anymore
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
148 lines
6.7 KiB
Markdown
148 lines
6.7 KiB
Markdown
# Deployment bootstrap
|
|
|
|
ZDDC tools (archive, transmittal, classifier, mdedit, landing) are single-file
|
|
HTML bundles. The bootstrap pattern lets you install once on a deployment and
|
|
update by editing a few lines, without re-uploading multi-megabyte HTML files.
|
|
|
|
End users install via a short copy-paste shell snippet from the home page's
|
|
"Install on your server" section. The snippet uses `curl` to fetch either
|
|
the current stable HTMLs (self-contained) or tiny level-2 stubs (channel
|
|
trackers) into the deployment directory. The published stubs live under
|
|
`https://zddc.varasys.io/bootstrap/`:
|
|
|
|
- `bootstrap/level1/<tool>.html` — same-origin level-1 stubs (4 tools, no
|
|
landing — landing only lives at deployment root).
|
|
- `bootstrap/track-{stable,beta,alpha}/<tool>.html` — per-channel level-2
|
|
stubs (5 tools each).
|
|
|
|
Both directories are produced by the project's top-level `build.sh` from
|
|
`bootstrap/level{1,2}.html.tmpl`.
|
|
|
|
## The two-level model
|
|
|
|
A typical `zddc-server` deployment looks like this:
|
|
|
|
```
|
|
<ZDDC_ROOT>/
|
|
index.html # landing tool (or bootstrap)
|
|
archive.html # archive tool (or bootstrap; site-wide channel switch lives here)
|
|
transmittal.html
|
|
classifier.html
|
|
mdedit.html
|
|
<project-A>/
|
|
archive.html # level-1 bootstrap → fetches ../archive.html
|
|
transmittal.html
|
|
classifier.html
|
|
mdedit.html
|
|
<project files…>
|
|
<project-B>/
|
|
archive.html # level-1 bootstrap (or pinned to a specific version)
|
|
…
|
|
```
|
|
|
|
- **Level-1 stubs** at `<project>/<tool>.html` always fetch the same-origin
|
|
`../<tool>.html`. They never touch `zddc.varasys.io`. Install them once;
|
|
they don't need to change.
|
|
- **At deployment root** (`<ZDDC_ROOT>/<tool>.html`), put either:
|
|
- the actual built tool HTML — fully self-contained install, no external
|
|
dependencies; or
|
|
- a level-2 bootstrap — resolves the desired channel against
|
|
`https://zddc.varasys.io/releases/manifest.json` (or skips that step for an
|
|
explicit `?v=X.Y.Z` pin) and fetches the asset from
|
|
`https://zddc.varasys.io/releases/<tag>/<tool>_v<X.Y.Z>.html`. Caddy at
|
|
`zddc.varasys.io` reverse-proxies that to the corresponding Codeberg
|
|
release-asset URL.
|
|
|
|
The site administrator switches the whole site to a channel by re-running
|
|
the `track-<channel>` install snippet from the home page — that overwrites
|
|
the root `<tool>.html` files with the matching level-2 stubs. A single
|
|
project can override one tool by editing just `<project-X>/<tool>.html`
|
|
(replace the relative `upstream` URL with an absolute zddc.varasys.io URL).
|
|
|
|
## Why two levels
|
|
|
|
The level-1 stubs let projects share a single source of truth for "which
|
|
build of the archive tool runs here." Switching channels is one file change
|
|
at the root; pinning a single project is one file change in that directory.
|
|
|
|
`document.write()` chains across both levels: level-1 fetches and writes,
|
|
the new document's level-2 script runs and writes again, the third write
|
|
is the actual tool. Origin stays at the deployment domain throughout, so
|
|
File System Access API, `crypto.subtle`, and `localStorage` all work and
|
|
preferences stay scoped to the deployment.
|
|
|
|
## Pinning options
|
|
|
|
There are two ways to choose a version: edit the stub for a permanent
|
|
pin, or pass a `?v=` URL parameter for a per-request override.
|
|
|
|
### 1. Permanent pin (edit the stub)
|
|
|
|
The level-2 stub resolves channels via `manifest.json` at runtime, so a
|
|
"pin to current stable" is the default — no editing required. To pin
|
|
this single tool to a specific version permanently, replace the level-2
|
|
stub with one that bypasses the manifest:
|
|
|
|
| To pin | Replace stub body with a fetch of |
|
|
|-----------------------------------------|-------------------------------------------------------------------------|
|
|
| Exact stable version `vX.Y.Z` | `https://zddc.varasys.io/releases/<tool>-vX.Y.Z/<tool>_vX.Y.Z.html` |
|
|
| Specific alpha/beta build | `https://zddc.varasys.io/releases/<tool>-vX.Y.Z-alpha.N/<tool>_vX.Y.Z-alpha.N.html` |
|
|
| Channel default (current implementation)| Resolves `<tool>-<channel>` against `releases/manifest.json` at runtime |
|
|
|
|
### 2. Per-request `?v=` parameter
|
|
|
|
Both stub levels honor a `?v=` URL parameter. The parameter survives the
|
|
`document.write()` chain, so it flows through level-1 → level-2 →
|
|
upstream automatically.
|
|
|
|
| URL parameter | Behavior |
|
|
|--------------------------------|-------------------------------------------------------|
|
|
| `?v=0.0.4` (or `?v=v0.0.4`) | tries `<tool>_v0.0.4.html` locally, then upstream |
|
|
| `?v=alpha` | switches to alpha channel |
|
|
| `?v=beta` | switches to beta channel |
|
|
| `?v=latest` | latest stable |
|
|
| (omitted) | the default baked into the stub |
|
|
|
|
When level-1 has `?v=…`, it tries `../<tool>_<suffix>.html` first (useful
|
|
when the admin has staged specific versions locally) and falls back to
|
|
`../<tool>.html` if 404 — which then forwards the parameter via level-2
|
|
if one is installed. So the same URL works whether the version is
|
|
staged locally, served by a level-2 stub, or both.
|
|
|
|
Stable releases are immutable. Alpha and beta channel files are
|
|
overwritten in place each time their channel is rebuilt; expect them to
|
|
change without notice. The build label rendered on the tool page tells
|
|
you what you are running (date + commit SHA for alpha/beta, version
|
|
number for stable).
|
|
|
|
## Auditing what's installed
|
|
|
|
Every stub contains a `fallback` (level-1) or `upstream` (level-2)
|
|
constant. To see what each tool / project on the deployment points at:
|
|
|
|
```sh
|
|
grep -rn "fallback\|upstream" <ZDDC_ROOT>
|
|
```
|
|
|
|
## CORS prerequisite (level-2 only)
|
|
|
|
A level-2 fetch is cross-origin (deployment → `zddc.varasys.io`). The
|
|
upstream must serve `Access-Control-Allow-Origin: *` (or a list including
|
|
your deployment origin) on `manifest.json` and on each released asset.
|
|
Verify with:
|
|
|
|
```sh
|
|
curl -I https://zddc.varasys.io/releases/manifest.json | grep -i access-control
|
|
curl -I https://zddc.varasys.io/releases/archive-v0.0.2/archive_v0.0.2.html \
|
|
| grep -i access-control
|
|
```
|
|
|
|
Level-1 fetches are same-origin so no CORS is involved.
|
|
|
|
## Templates
|
|
|
|
`level1.html.tmpl` and `level2.html.tmpl` are the source of truth. The
|
|
project's top-level `build.sh` substitutes `{{TOOL}}`, `{{TOOL_TITLE}}`,
|
|
`{{CHANNEL}}`, and `{{FAVICON}}` to produce the per-tool stubs published
|
|
under `website/bootstrap/level1/` and `website/bootstrap/track-<channel>/`,
|
|
which the install snippets curl from `https://zddc.varasys.io/bootstrap/`.
|