[Unit] Description=OpenFUT Core (PRODUCTION) — authoritative economy state Documentation=file:///home/alex/OpenFUT/scripts/systemd/README.md # PRODUCTION TEMPLATE — NOT INSTALLED. Deploy only via the promotion plan in # `06 Operations/OpenFUT Service Supervision (staging-proven).md`. # # Core is the SINGLE WRITER of prod-core.db (verified by lsof: exactly one # process holds it open). Nothing here may be templated into a second instance. After=network-online.target docker.service openfut-netns.service Wants=network-online.target Requires=openfut-netns.service # StartLimit* MUST live in [Unit]: systemd 252 silently IGNORES them in # [Service] (`systemd-analyze verify` flags it), which would have left the # crash-loop ceiling at the 10s/5 default instead of the intended 60s window. StartLimitIntervalSec=60 StartLimitBurst=5 [Service] Type=exec # root, matching the current production processes exactly. Supervision changes # HOW the process is started, never what it is or what it can reach. User=root # The container's netns, published by openfut-netns.service. This replaces the # hand-typed `nsenter --net=/proc//ns/net` in the runbook: same namespace, # no hardcoded pid, and re-resolved on every start. NetworkNamespacePath=/run/netns/openfut EnvironmentFile=/etc/openfut/core.env # An IMMUTABLE promotion artifact, not target/release. A later `cargo build` # must not be able to change what production is running — the same invariant # the promotion process already relies on. ExecStart=/home/alex/openfut-migration/promote-contract-20260822-184409/artifacts/openfut-core KillSignal=SIGTERM KillMode=mixed # Generous, so a WAL checkpoint is never SIGKILLed mid-write. Observed shutdown # is sub-second. TimeoutStopSec=30 Restart=on-failure RestartSec=5s StandardOutput=journal StandardError=journal SyslogIdentifier=openfut-core [Install] WantedBy=multi-user.target