3.5 KiB
id, title, theme, status, created, date_source, order
| id | title | theme | status | created | date_source | order |
|---|---|---|---|---|---|---|
| infra/opm-officer-s-own-process-manager | OPM — Officer's own process manager, or at least its own PM2 | infra | open | 2026-08-21 | stated | 0 |
OPM — Officer's own process manager, or at least its own PM2. Raised 2026-08-21. Taken as: give Officer's processes a manager of their own, named OPM, rather than sharing one daemon with whatever else lives on the host — worth doing for separation of concerns alone, even without any new capability.
The argument is that Officer is now a fleet of processes, not a process. pm2 jlist counts 13 officer
entries on officer-dev and 19 on alpha (verified 2026-08-21), and every one of them is a peer of
the server rather than a child of it. They are managed today by a generated ecosystem.config.cjs
(bun run gen:ecosystem) on a PM2 daemon that belongs to the login user, not to Officer.
What sharing costs, all of it already written down in CLAUDE.md: pm2 restart ecosystem.config.cjs
bounces every sidecar including the vault, so the safe habit is --only <name> and the unsafe one
looks identical; a pm2 list mixes Officer's processes with other projects' and the rule "nothing here
should touch them" is a convention rather than a boundary; and the documented list of entries goes stale
every time a sidecar lands, because nothing owns it. Note the foreign-process case is host-dependent —
mybiblepal-api and mybiblepal-audio are named in CLAUDE.md as sharing this daemon, and neither is
running on officer-dev or alpha today.
Open, and the owner's call: whether OPM is a genuinely new supervisor or PM2 kept underneath with its own
daemon, namespace and CLI wrapper — which would buy the separation at a fraction of the cost, since the
ecosystem.config.cjs generation, the naming convention and the restart discipline all already exist.
Decided 2026-08-25: it is happening, and it answers the open question above. OPM is a genuinely new supervisor, not PM2-with-a-wrapper — because the next requirement needs something PM2 was never built for: OPM should sit ON the Docker network, so a container-backed dependency never needs a published host port at all.
Verified on this host what that would remove. docker network ls shows dedicated bridge networks
already in place (officerdev, services, nginx) — the grouping this asks for exists, containers are
just not reached through it. What IS published today, purely so a host process can reach a container,
is the thing this closes: officer-postgres is 127.0.0.1:5432->5432, gitea is
127.0.0.1:9004->3000 and 127.0.0.1:10023->22. Every one of those bindings exists for exactly one
reason — a process on the host, not in Docker, needs to reach the container — and every one is a port
that answers on localhost to anything else running as the same user, not only to Officer.
If OPM itself runs attached to the Docker network (or as a container on it), it reaches
officer-postgres:5432 and gitea:3000 by container name, over the network Docker already isolates,
and the host-published bindings above stop being necessary for Officer's own processes to work. Whether
they can be removed entirely depends on who ELSE reaches them this way — POSTGRES_URL and any
migration/backup tooling run from a plain shell would need to move onto the network too, or keep a
narrower published port for that one purpose. That accounting is the first real task once this starts,
not an assumption to build on.