docs(deployment): wie eine Instanz mehrere Repositories bedient
Der aus Sitzung C nach E übertragene Doku-Punkt: docs/deployment.md beschreibt die Registry jetzt betrieblich — klonen, vorbereiten, in ~/.werkator.yml eintragen, neu starten. Dazu die Regeln, die beim Eintragen weh tun, wenn man sie nicht kennt: Der Name ist Routen-Segment und Umschalter-Eintrag und muss eindeutig sein (ein Doppel bricht den Start ab, ebenso ein Eintrag, der kein git-Repository ist), eine unlesbare Konfiguration überspringt nur ihr Repository, geteilte Zugangsdaten können einmal im defaults-Block liegen, und die Unit behält ihren Namen — sie gehört der Instanz, nicht einem Repository. Dazu, was die Adressen tun: mit einem Repository bleibt jede URL, wie sie war; mit mehreren tragen Seiten und API das Repository, und die unscoped Pfade meinen weiterhin das bediente. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c82f2a965c
commit
91e1dd47a3
@@ -81,6 +81,50 @@ User services stop at logout unless lingering is enabled once per user:
|
||||
loginctl enable-linger "$USER"
|
||||
```
|
||||
|
||||
## Serving Several Repositories
|
||||
|
||||
One instance serves a *set* of repositories (ADR 0009): one service, one port, one UI, one watcher loop, one control token.
|
||||
Adding a repository is editing a registry entry — never a data migration, because everything repository-specific already lives inside the repository (`.git/werkator/`: machine config with secrets, build results, auto-build slots, worktrees).
|
||||
|
||||
1. **Clone it** on the host, next to the ones already served:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<owner>/<repo>.git ~/repos/<repo>
|
||||
```
|
||||
|
||||
2. **Prepare it** like any watched repository — the machine config with the git credentials, and the sandbox policy if the host needs one:
|
||||
|
||||
```bash
|
||||
cd ~/repos/<repo> && java -jar ~/bin/werkator.jar init
|
||||
# fill in git.account and git.token in .git/werkator/.werkator.yml
|
||||
```
|
||||
|
||||
Credentials shared by every repository of the same forge can live once in the instance file's `defaults` block instead (`docs/configuration.md`); they merge below each repository's own layers, so a repository may still override them.
|
||||
The repository's own `.werkator.yml` — its builds — is committed and comes with the clone.
|
||||
|
||||
3. **Register it** in `~/.werkator.yml` of the user running the service:
|
||||
|
||||
```yaml
|
||||
repositories:
|
||||
- path: ~/repos/werkator
|
||||
- path: ~/repos/<repo>
|
||||
name: <short-name> # optional; default is the directory basename
|
||||
```
|
||||
|
||||
The name is the route segment (`/repos/<name>/…`) and the UI's switcher entry, so it must be unique: a duplicate aborts the start naming this file, and so does an entry that is no git repository.
|
||||
A repository whose configuration Werkator must not read (a version violation) is skipped with an error — the others keep building.
|
||||
|
||||
4. **Restart** the service; startup recovery re-enqueues what was in flight:
|
||||
|
||||
```bash
|
||||
systemctl --user restart werkator-<repo-name>.service
|
||||
```
|
||||
|
||||
The service unit keeps the name it was installed with — it is the instance's unit, not one repository's.
|
||||
With one registered repository every URL stays what it was; with several, the pages and the API carry the repository (`/repos/<name>/…`, `/api/repos/<name>/…`), the unscoped paths keep meaning the repository the instance was started in, and the navigation shows a switcher.
|
||||
The watcher polls every repository in its own guard: an unreachable origin is that repository's report in the health banner, and the others are polled regardless.
|
||||
`executor.maxConcurrent` is the global cap across all of them, and builds take slots in enqueue order (FIFO).
|
||||
|
||||
## Operating the Service
|
||||
|
||||
```bash
|
||||
|
||||
@@ -68,7 +68,7 @@ The pinning model is untouched: pinned keys still come from each repo's machine
|
||||
- ~~Latest/branches/history views group by repo or gain a repo column; one instance-wide metrics page; one control token.~~ — done 2026-09-03, decided against the column: the pages stay per repository and the navigation gains a **repository switcher** (a row's actions need the repository anyway, branches come from one origin, artifacts from one store — and with one repository a column is noise). Metrics page and control token stay instance-wide as planned.
|
||||
- Gitea status links use the repo-scoped URLs — the permanent artifact links do (`BranchPermalinks.permanentUrl` takes the prefix, because the key is a hash of the build name alone and two repositories both having `main` would otherwise share one URL); the commit-status target URLs posted by `GiteaStatusPublisher` are carried over to session E, where the instance actually serves two repositories.
|
||||
- Also done: `RunningBuild` carries its `RepoContext` (the carry-over from session C), so the current-builds views and the watcher's worktree pruning tell repositories apart, and `cancel` refuses a key that is not recorded in the named repository.
|
||||
- Carried over to session E: the commit-status URLs; `docs/deployment.md` gets the registry setup.
|
||||
- Carried over to session E: the commit-status URLs. ~~`docs/deployment.md` gets the registry setup~~ — done 2026-09-03: section "Serving Several Repositories" (clone, prepare, register, restart) with the name rules, the per-repository guard, and what the URLs look like with one repository and with several.
|
||||
|
||||
### E — Rollout on mih34: Werkbaum joins
|
||||
|
||||
|
||||
Reference in New Issue
Block a user