Skip to content

Commit 9dd4d37

Browse files
amtiYoclaude
andcommitted
docs: write down how this stack is actually deployed
Releasing was documented in every repository; deploying was documented in none. docs/releases.md stopped at "deploy it, and check the running version says what it should" and never said how, which is how a family that pins images by digest still had no written answer to "which digest, set where, and what happens when it goes wrong". The gap got worse the same day the stacks moved from building on the host to pulling a published image: the procedure changed and the documentation did not. An agent or a person reading this repository had to reconstruct it from the compose file. The new Deploying section names this stack's directory on the host, the env file that selects the image, the variable that names it, the networks it needs, the per-stack traps worth knowing, and what a rollback actually is. AGENTS.md points at it and repeats the two rules easiest to get wrong: nothing is built on the host, and a digest is pinned rather than a tag. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxNv1rk7jMQtb9tMBREc5B
1 parent e9a6e7e commit 9dd4d37

3 files changed

Lines changed: 95 additions & 0 deletions

File tree

‎AGENTS.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,17 @@ Branchy is licensed under Apache-2.0. Preserve the root `LICENSE` and `NOTICE` f
146146
`editEphemeralMessageText`. Notifications are rich messages and group
147147
overlays are ephemeral ones, so a server without them makes Branchy mute.
148148

149+
## Deploying
150+
151+
Do not invent a deploy. [`docs/releases.md`](docs/releases.md) has a **Deploying**
152+
section describing this stack exactly: which host directory it lives in, which
153+
env file names the image, which networks it needs, and how to roll back. Read it
154+
before touching anything on the host.
155+
156+
Two rules that hold everywhere and are easy to get wrong:
157+
158+
- **Nothing is built on the host.** A production stack pulls the image the
159+
release workflow published. A `build:` section in a production manifest is a
160+
bug.
161+
- **Pin the digest, not the tag.** A tag moves; a digest names one build that was
162+
tested, and a rollback becomes one line with nothing to rebuild.

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ Use this section for changes that are merged but not released yet.
6565

6666
### Added
6767

68+
- `docs/releases.md` gained a **Deploying** section, and `AGENTS.md` points at it.
69+
Releasing was documented; deploying was not, in any repository in the family —
70+
the process stopped at "deploy it" and never said how. That gap mattered more
71+
after the stacks moved from building on the host to pulling a published image,
72+
because the procedure changed on the same day. The section names this stack's
73+
host directory, its env file, the variable that selects the image, the networks
74+
it needs, and what a rollback actually is.
75+
6876
- An **About** card, reachable from the main menu and from the group panel. It
6977
states the running version — the same string `/healthz` reports — plus the
7078
supported events, the repository, the license, and the admin contact. Until

‎docs/releases.md‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,79 @@ the whole rollback — and then publish a new patch that fixes what went wrong.
9292
A version that was published is a fact about what existed. Rewriting it makes
9393
every other record of it wrong.
9494

95+
## Deploying
96+
97+
The host is WS04. Every stack lives in `/opt/stacks/<stack>` and is driven by the
98+
`ws04` CLI, which exists on the operator's machine and reaches the host over the
99+
LAN. Nothing here is built on the host any more: a stack pulls the image the
100+
release workflow published and runs that. If you find a `build:` section in a
101+
production manifest, that is a bug, not a shortcut.
102+
103+
### One deploy
104+
105+
```sh
106+
ws04 deploy branchy --dry-run --yes # prints what it would do, changes nothing
107+
ws04 deploy branchy --yes
108+
```
109+
110+
`deploy` snapshots the stack's compose, env and image ids into
111+
`/opt/stacks/.ws04/deploy-snapshots/branchy/<timestamp>`, pulls, brings the stack
112+
up, waits up to ninety seconds for the container to report healthy, and **rolls
113+
back on its own** if it does not. The snapshot is kept either way.
114+
115+
### Pointing the stack at a version
116+
117+
The image is chosen by one variable in the stack's env file on the host, not by
118+
anything in this repository:
119+
120+
```sh
121+
BRANCHY_IMAGE=ghcr.io/freshlabdev/branchy@sha256:<digest>
122+
```
123+
124+
Pin the **digest**, not the tag. A tag can be moved; a digest names one build
125+
that was tested, so a rollback is one line with nothing to rebuild, and
126+
`docker inspect` on the running container answers which commit it came from. The
127+
digest of a release is in its GitHub Release notes, or:
128+
129+
```sh
130+
gh api /orgs/FreshLabDev/packages/container/branchy/versions \
131+
--jq '.[] | select(.metadata.container.tags[]? == "<tag>") | .name'
132+
```
133+
134+
The variable has no default. An unset one stops the stack with a message naming
135+
it, rather than quietly starting something else.
136+
137+
### Rolling back
138+
139+
Set `BRANCHY_IMAGE` to the previous digest and deploy again. That is the whole
140+
rollback — the images are still on the host, and nothing is rebuilt. Then publish
141+
a patch that fixes what went wrong; never retag or delete the bad release.
142+
143+
### What this stack needs to exist
144+
145+
| | |
146+
|:--|:--|
147+
| Stack | `branchy` — `/opt/stacks/branchy` |
148+
| Manifest | [`deploy/ws04/compose.yaml`](deploy/ws04/compose.yaml) in this repository |
149+
| Env file | `.env` on the host, never in git |
150+
| Networks | `core_net` (core-postgres), `management` (the Cloudflare tunnel that terminates the GitHub OAuth callback and the repository webhooks) |
151+
152+
Branchy is the only stack on `management`. Without it the OAuth callback and
153+
every GitHub webhook delivery stop arriving, and the bot looks idle rather than
154+
broken.
155+
156+
### Checking what is running
157+
158+
```sh
159+
ws04 container list # health of everything
160+
ws04 logs branchy --since 1h
161+
ws04 container inspect branchy # includes the image digest
162+
```
163+
164+
The bot also reports its own version — from the About card in Telegram, and from
165+
its health endpoint where it has one. Those two and `docker inspect` should
166+
agree; if they do not, something was deployed by hand.
167+
95168
## Verification
96169

97170
The local machine may not have `go` in `PATH`; Docker is the reliable route:

0 commit comments

Comments
 (0)