deploy: scope page to the dev's job — drop operator commands

Devs never deploy — that's a central ops tool. Remove operator-facing
content and keep only what a dev is responsible for (a conforming compose).

- remove the 'Onboarding a service' section (deploy <host> <workspace>
  <git-url> command + deploy-key internals) and the 'How deploy fills it in'
  docker-ps collision table + <workspace>/<name> naming internals
- replace with 'Deployment is handled centrally': a note that devs run no
  deploy commands, plus the kept dev-facing context that the env is
  GENERATED at deploy time so ${LOGS_DIR}/${CONFIG_DIR}/${MOUNTS_DIR}
  resolve without them (less ambiguous than just 'it's handled')
- trim operator leftovers: svc-<ws>-<name> unit ref, dangling '(below)',
  and the /srv/config/<ws>/<name> path in the secrets note

Compose convention, uid 1337, restart, mounts tier, layer caching, uv,
subprocess knobs all unchanged. Verified in-browser; build --strict clean.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-01 02:04:17 -04:00
parent 08ad37eddc
commit 0ebd6f86b0
+21 -51
View File
@@ -142,8 +142,7 @@ volumes:
```
1. The service key is always **`svc`** — never a repo-specific name, never a
`container_name`. Our tooling keys off `svc` (the `svc` command, the
`svc-<workspace>-<name>` unit).
`container_name`. The ops tooling keys off `svc`.
2. Run as the shared **`services`** account (**uid/gid 1337**, fixed fleet-wide).
**No** in-container `user`/`useradd` — set it here. This is the one identity
line that stays; it's not repo-specific.
@@ -173,58 +172,29 @@ volumes:
!!! tip "The `${VAR:-./default}` pattern"
Host paths use a variable with a local fallback. Locally, `docker compose up`
needs nothing set — it uses `./logs`, `./config` (and `./mounts` if you enable
it). On the fleet, the deploy layer sets the real values (below), so the same
file works both places.
it). When deployed, the ops tooling sets the real values, so the same file works
both places.
## How deploy fills it in
## Deployment is handled centrally
At deploy time we set the variables your compose reads, so identity and host paths
are injected — not baked into your file. You can rely on these being present:
!!! note "You don't run any deploy commands"
All services are deployed centrally by the ops tooling. You don't pick a host,
manage keys, or run anything — just make your repo follow the compose convention
above and it's deployable.
At deploy time the tooling **generates** the environment your compose reads, so the
`${...}` variables resolve without anything from you. You can rely on these being
set — that's why your compose works unchanged on the fleet:
```
COMPOSE_PROJECT_NAME=<workspace>-<name>
LOGS_DIR=/srv/logs/<workspace>/<name>
CONFIG_DIR=/srv/config/<workspace>/<name>
MOUNTS_DIR=/srv/mounts/<workspace>/<name> # dir auto-created; mount line opt-in
LOGS_DIR # your host log dir -> ${LOGS_DIR}
CONFIG_DIR # your host config dir -> ${CONFIG_DIR}
MOUNTS_DIR # optional host data dir -> ${MOUNTS_DIR} (if you enable the mount)
```
Which makes ownership obvious and collisions impossible:
| item | value |
| --- | --- |
| container | `<workspace>-<name>-svc-1` |
| volume | `<workspace>-<name>_cache` |
| network | `<workspace>-<name>_default` |
| logs | `/srv/logs/<workspace>/<name>/` |
!!! warning "What `<workspace>` and `<name>` are"
- **`<workspace>`** — who owns it: an individual dev (`ricky`, `xattam`, …) or a
category (`tpv`, `web`, `bots`, …).
- **`<name>`** — the git repo name, lowercased, by default. Overridable at
deploy time.
Host paths live under `/srv/<kind>/<workspace>/<name>/` (config, logs, and mounts if
enabled), all owned by the `services` user (uid/gid **1337**). You never write these
paths in your compose — you read the injected `${...}` variables.
## Onboarding a service
One command registers and starts a service:
```
deploy <host> <workspace> <git-url> [name]
```
It registers the service, generates a per-repo **read-only deploy key on the host**
(the private key never leaves the box), pushes the public key to the repo's Gitea
deploy keys automatically, clones the code, and installs and starts the service's
unit. No manual key paste, no host setup on your end.
!!! note "If your service won't start or its logs aren't persisting"
That's usually a host-side bind-mount **ownership** thing — the kind of detail
**we sort out at deploy time**, not something you need to chown or provision.
If a bot won't come up or logs/caches keep vanishing, flag it and we'll fix it.
Stick to the generic `compose.yaml` above and let us handle the host.
Write your logs and config to those mount points and you're set. If a service won't
come up or its logs aren't persisting, that's a host-side detail on our end — flag it
and we'll sort it.
## Layer caching
@@ -297,9 +267,9 @@ services:
!!! warning "Secrets never go in the image"
We do **not** commit secrets (usually, lol). They stay **gitignored** and live
on the host under the config dir (`/srv/config/<workspace>/<name>/`), reaching
your container read-only via `${CONFIG_DIR}`. Add them to `.dockerignore` so a
`COPY . .` can't sweep them into a layer.
on the host in your config dir, reaching your container read-only via
`${CONFIG_DIR}`. Add them to `.dockerignore` so a `COPY . .` can't sweep them
into a layer.
Rotating a secret is a host-side edit — update the file and the service picks it up
on restart. No rebuild, and nothing you run: flag it and we handle the restart.