feat(nix): flake.nix exposing lib.mkWebapp #98
No reviewers
Labels
No labels
app:activities
app:chat
app:events
app:forum
app:libra
app:market
app:restaurant
app:tasks
app:wallet
app:webapp
bug
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
aiolabs/webapp!98
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/flake-mkwebapp"
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?
Closes #97 — adds the nix build path so deploy/server-deploy hosts can call
inputs.webapp.lib.mkWebapp { brandDir, app }per-host instead of running their own derivation. Follow-up to #96 (brand kit Phase 1, merged into dev).What ships
flake.nixexposes:lib.mkWebapp { pkgs, brandDir ? ./branding/default, app ? "main" }— system-agnostic builder returning astdenv.mkDerivation.packages.<system>.<app>for each ofmain / events / wallet / chat / market / forum / tasks / restaurant / libra, all using the aiolabs default brand (CI / local sanity).packages.<system>.default = packages.<system>.main.flake.lockpinsnixpkgs(nixos-unstable) andflake-utils.How it builds
pkgs.fetchPnpmDeps(withfetcherVersion = 3+pkgs.pnpm_10explicit) snapshots all NPM packages frompnpm-lock.yamlinto a hash-pinned fixed-output derivation.pkgs.pnpmConfigHookinstallsnode_modulesfrom the snapshot offline.pkgs.autoPatchelfHook+stdenv.cc.cc.libpatch the prebuilt@img/sharp-libvips-linux-*binaries so they run under the nix sandbox.BRAND_DIRenv points at thebrandDirarg (a/nix/store/...path).BRAND_APPenv carries the standalone name (empty for the hub).CI=truebypasses pnpm 10's interactive modules-purge prompt.pnpm run build(hub) orpnpm run build:<app>(standalone) producesdist/ordist-<app>/, which gets copied to$out.Design notes
pkgs.pnpm_10is pinned explicitly (notpkgs.pnpm) so the pnpmDeps hash stays stable across downstream nixpkgs versions. The flake's nixos-unstable currently haspnpmfloating at 11.5.1, butpnpm_10stays at the 10.x major series that matchespackageManager: pnpm@10.33.0inpackage.json. Downstream consumers using a different nixpkgs still get a working build as long as their nixpkgs also haspnpm_10(it has been in nixpkgs for a long time).Sharp under nix worked first try with autoPatchelfHook — modern sharp 0.33+ ships prebuilt libvips as a separate npm package (
@img/sharp-libvips-linux-x64) which fetchPnpmDeps captures as a tarball. The .so files inside get patched at install time. No need to build libvips from source.Test plan
nix build .#main→dist/index.htmlwith<title>AIO Hub</title>+ 6 icons indist/icons/nix build .#events→dist-events/withmanifest.name = "AIO"lib.mkWebapp { pkgs = <external>; brandDir = /tmp/fixture; app = "events"; }— fixture'sbrand.json { name: "Sortir", themeColor: "#dc2626", ... }propagates to manifest + HTML title; fixture'slogo.pngresolves via@brand/and gets hashed intodist-events/assets/logo-<hash>.png.Cross-references
🤖 Generated with Claude Code
Establishes the nix build path so deploy/server-deploy can call inputs.webapp.lib.mkWebapp { brandDir, app } per-host instead of running its own derivation. lib.mkWebapp { pkgs, brandDir ? ./branding/default, app ? "main" } returns a stdenv.mkDerivation that: - Uses pnpmConfigHook + fetchPnpmDeps (fetcherVersion = 3) to install node_modules from a hash-pinned snapshot, offline. - Wires brandDir into the BRAND_DIR env var so vite-branding.ts and pwa-assets.config.ts resolve the right brand. - Sets BRAND_APP from `app` so per-standalone overrides (branding/<dep>/icons/<app>/logo.*) work. - autoPatchelfHook + stdenv.cc.cc.lib patch the prebuilt @img/sharp-libvips-linux-x64 binaries to run under the nix sandbox. - Runs `pnpm run build` for the hub or `pnpm run build:<app>` for a standalone, then copies the resulting dist/ or dist-<app>/ into $out. Per-system exposure: - packages.<app> for each of main/events/wallet/chat/market/forum/ tasks/restaurant/libra — exercises the builder under CI. - packages.default = packages.main. Closes aiolabs/webapp#97. Server-deploy hosts can now migrate via aiolabs/server-deploy#8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Two issues found when calling lib.mkWebapp from an external nixpkgs (server-deploy's scenario): - pnpm 10 in the sandbox aborts with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY when it sees a modules-purge prompt without a TTY. CI=true is pnpm's documented bypass; harmless on builds that don't need it. - Pinning pkgs.pnpm leaves it floating with the consumer's nixpkgs (flake's nixos-unstable has pnpm 11.5.1, system nixpkgs has 10.33, etc.). pnpmDeps hash is per-pnpm-version so a floating pnpm means consumers hit hash mismatches. Pinning pkgs.pnpm_10 locks to the same major series that produced the lockfile (package.json's packageManager: pnpm@10.33.0) while still allowing minor drift inside major-10. New pnpmDeps hash reflects pnpm_10's snapshot format. Verified end-to-end: `nix build --impure --expr '...lib.mkWebapp { brandDir = /tmp/fixture; app = "events"; }'` with an external pkgs produces a Sortir-branded dist-events (manifest name "Sortir", theme #dc2626, bg #fff5f5, HTML title "Sortir"). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>