CI / test (push) Successful in 1m16s
Phase 3 had a block duplicated into itself, including an unchecked 'EndpointSource becomes dynamic' sitting directly under the checked line saying it was wired. Several phase 5 items had shipped without being ticked. The units were only ever on the machines and in a scratch directory, which makes them undocumented operational knowledge rather than part of the project. KillMode=process in particular is not obvious and not optional: without it systemd takes the engines down with the agent, turning a thirty-second upgrade into a model reload on every node. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
35 lines
1.4 KiB
Markdown
35 lines
1.4 KiB
Markdown
# systemd units
|
|
|
|
Two roles, two units. Copy the one you need to `/etc/systemd/system/`, put the
|
|
matching configuration in `/etc/llmgw/`, and `systemctl enable --now` it.
|
|
|
|
## The control plane — `llmgw-server.service`
|
|
|
|
Runs unprivileged. It needs to read its own TLS key, so that file must belong to
|
|
the `llmgw` user and nothing else:
|
|
|
|
```
|
|
useradd --system --home-dir /var/lib/llmgw --shell /usr/sbin/nologin llmgw
|
|
chown llmgw:llmgw /etc/llmgw/server-key.pem
|
|
chmod 0400 /etc/llmgw/server-key.pem
|
|
```
|
|
|
|
`StateDirectory=llmgw` creates `/var/lib/llmgw` with the right owner, which is
|
|
where the store belongs. `ProtectSystem=strict` makes the rest of the filesystem
|
|
read-only, so anything else it writes to has to be named explicitly.
|
|
|
|
## The agent — `llmgw-agent.service`
|
|
|
|
Runs as root, because it launches engines and needs device access.
|
|
|
|
`KillMode=process` is the line that matters and the reason this file exists
|
|
rather than being generated. Without it, systemd kills the whole control group
|
|
on stop — including the engines, which hold a loaded model and are serving
|
|
traffic. Engines are meant to outlive an agent restart: the router talks to them
|
|
directly, and the agent adopts them again when it comes back. Taking them down
|
|
with the agent turns a thirty-second upgrade into a full model reload on every
|
|
node.
|
|
|
|
systemd will log `Found left-over process ... in control group while starting
|
|
unit. Ignoring.` on the next start. That is the mechanism working, not a fault.
|