T-2 — Migrate constructionbot from dynamic-contained to dynamic-nix #11
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Labels:
infrastructure,deploymentDepends on: T-1;
deepnet/dit-client#90;deepnet/dit-client#91; Arc 0cutover accepted.
Rationale
The app runs on the legacy podman path by a one-day timing accident, not a
decision. First commit 2026-08-12 16:29; the
dynamic-nixarchetype merged todit-clientmain the same day (PR #45) and shipped in ditc v1.3.0 on2026-08-13.
Spec 012 (
deepnet/infra-template,specs/012-nix-native-app-execution) makesnix-native the intended default for new apps and names two defects in the podman
model this app is living with:
dynamic-containedapp was unreachable until dit-client #31 added-p 127.0.0.1:PORT:PORT. This app carries the scar as a hand-maintainedcomment in
ingress.yamlwarning thatupstream: 127.0.0.1:58402and thedeploy workflow's publish flag "move together."
so podman adds a second, redundant isolation layer.
Two further wins specific to this repo:
every source edit; HEAD (
ad91fb7) is atouch src/main.rshack workingaround it.
nix build .#defaulton a runner with a warm store is incrementalby construction. This deletes the problem class rather than optimizing it.
dit-nix-app-runinjectsDynamicUser=yes,PrivateTmp,ProtectSystem=strict,ProtectHome,ReadWritePaths=/data/apps/<slug>wrapper-side viasystemd-run --property=.A regenerated workflow cannot strip them. Today's
--read-only --cap-drop=ALL --tmpfsexist only because the workflow was hand-restored from commit6def9af; the current ditc podman generator emits no hardening flags at all,so the next
ditc deploywould silently drop them again. That recurringgotcha dies with this migration.
Scope
flake.nixat the repo root exposingpackages.<system>.default, builtwith
rustPlatform.buildRustPackage. Reference implementation:deepnet/chess(symbio tenant) is a live Rust app on this exact path.bin/constructionbotand theapp must bind
127.0.0.1:58402. The port is fixed at build time — thewrapper passes no
PORTenv and no argv.config.rs'sdefault_listenmustreflect this.
poppler-utils(pdftotext) becomes a nix runtime dependency — wrap thebinary so
pdftotextis onPATH, replacing theapt-get installin theruntime stage.
manifest.yamldit.archetypetodynamic-nixandingress.yamltypetodynamic-nix.current workflow carries and the ditc generator omits:
cargo test --lib,cargo clippy --all-targets -- -D warnings,scripts/no_hardcoded_endpoints.sh,scripts/check_ingress_port.sh, and thesecret-scrub step.
Containerfilein the same commit as the flake lands (atomicmigration — no intermediate state where both build paths exist).
refs-file mechanism (root wrapper AppRole fetch) rather than the podman path's
runner-side
bao kv get+--env.Acceptance criteria
nix build .#defaultsucceeds on the self-hosted runner and producesbin/constructionbot.constructionbot.apps.gallahercompanies.combehind Caddyforward-auth, and the
X-Gal-Fwd-Proofheader still validates(
src/middleware.rsunchanged).FORWARD_AUTH_SECRETpresent./healthzreturns 200; migrations applied on boot;pdftotextresolvablefrom the app's
PATH— verify by processing a Morella fixture end to end.dit-nix-app-run rollbackreturns the app to the previous store path and itserves 200.
nix-app-runtime-restart.service.not merely declared — depends on #90. Verify a disallowed destination is
refused.
MemoryMaxandTasksMaxare set on the unit — depends on #91. Verify withsystemctl show app-constructionbot. This bound matters: the app spawnspdftotextover vendor-supplied PDFs (untrusted input), and today--memory 512m --pids-limit 256is the only thing stopping a hostile PDF fromexhausting the tenant container and taking down co-tenant apps.
Rollback plan
Keep the
dynamic-containedworkflow on a branch until the nix path has servedproduction traffic for one full digest cycle (24h, so the 07:00 cron and the
mailbox poller both exercise). Reverting is: restore
Containerfile+ thepodman workflow, flip
manifest.yamlandingress.yamlback, push.Do not start before
Arc 0 cutover is accepted. Do not change the deployment substrate under a system
Jake is mid-validation on, that writes legally binding records.