1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-10-09 12:55:00 +02:00

build: build frontend in Nix, remove static from git tracking

Add frontendDeps (FOD) and frontendStatic derivations to flake.nix so
that nix build handles the Vite bundle automatically. The archivr_server
derivation now copies from ${frontendStatic} instead of
${./crates/archivr-server/static}.

crates/archivr-server/static/ is excluded from git tracking (.gitignore);
the aarch64-darwin node_modules hash is included. Other systems use a
placeholder hash — run `nix build 2>&1 | grep 'got:'` to obtain theirs.

Update AGENTS.md and docs/README.md to reflect the new workflow.
This commit is contained in:
TheGeneralist 2026-10-04 22:53:42 +02:00
parent 699eb7f62d
commit 4f3b2968b6
4 changed files with 66 additions and 5 deletions

5
.gitignore vendored
View file

@ -11,6 +11,11 @@
!docs/branding/** !docs/branding/**
!crates !crates
!crates/** !crates/**
# Static assets are built by Nix (frontendStatic derivation in flake.nix).
# Do not commit them; `nix build` produces them from frontend/src/.
crates/archivr-server/static/
crates/archivr-server/static/**
!vendor !vendor
!vendor/** !vendor/**

View file

@ -74,11 +74,13 @@ cargo build --release -p archivr-server
# Frontend (Bun, from frontend/) # Frontend (Bun, from frontend/)
bun install bun install
bun run dev # Vite dev server bun run dev # Vite dev server
bun run build # → ../crates/archivr-server/static (served by the server) bun run build # → ../crates/archivr-server/static (gitignored; only needed for bare cargo run)
# Nix # Nix
nix develop # devshell: yt-dlp, nushell, uv, twitter-api-client nix develop # devshell: yt-dlp, nushell, uv, twitter-api-client
nix build .#archivr-server # also .#archivr-cli, .#archivr-all nix build .#archivr-server # also .#archivr-cli, .#archivr-all; builds frontend automatically
# If frontendDeps hash is stale (after bun.lock/package.json change):
# nix build 2>&1 | grep "got:" → paste hash into flake.nix frontendDepsHash
# Docker # Docker
docker compose up -d # port 8080; config in ./config/archivr-server.toml (see docker/config.example.toml) docker compose up -d # port 8080; config in ./config/archivr-server.toml (see docker/config.example.toml)
@ -131,7 +133,7 @@ No CI is configured; no rustfmt.toml/clippy.toml — default `cargo fmt`/`clippy
- **Bun** is the frontend package manager (`frontend/bun.lock`); use `bun`, not npm/yarn. - **Bun** is the frontend package manager (`frontend/bun.lock`); use `bun`, not npm/yarn.
- Runtime binaries the app expects on PATH or via env vars: `yt-dlp`, Chromium, `single-file` (Node), Python 3 with `twitter-api-client`, `ffmpeg`. `nix develop` provides the dev subset. - Runtime binaries the app expects on PATH or via env vars: `yt-dlp`, Chromium, `single-file` (Node), Python 3 with `twitter-api-client`, `ffmpeg`. `nix develop` provides the dev subset.
- `.gitignore` is **default-deny with an allowlist** — new top-level files/dirs are invisible to git until explicitly allowed there. - `.gitignore` is **default-deny with an allowlist** — new top-level files/dirs are invisible to git until explicitly allowed there.
- Frontend build output (`crates/archivr-server/static/`) is generated; never hand-edit it. - Frontend build output (`crates/archivr-server/static/`) is generated by the `frontendStatic` Nix derivation; never hand-edit it, and do not commit it — it is excluded from git tracking. `nix build` is the standard workflow everywhere (local and NixOS) and builds the frontend automatically. `bun run build` only needed for bare `cargo run` one-off testing. When `bun.lock` or `package.json` changes, update `frontendDepsHash` in `flake.nix` for each system by running `nix build 2>&1 | grep "got:"` and pasting the reported hash.
- **yt-dlp is pinned to a specific GitHub release** in the `ytDlp` derivation in `flake.nix` (zipapp - **yt-dlp is pinned to a specific GitHub release** in the `ytDlp` derivation in `flake.nix` (zipapp
fetched from `github.com/yt-dlp/yt-dlp/releases`, wrapped with `python312` + `ffmpeg`) — not taken fetched from `github.com/yt-dlp/yt-dlp/releases`, wrapped with `python312` + `ffmpeg`) — not taken
from nixpkgs. Both the `archivr` and `archivr-server` wrappers set `ARCHIVR_YT_DLP` from it. Three from nixpkgs. Both the `archivr` and `archivr-server` wrappers set `ARCHIVR_YT_DLP` from it. Three

View file

@ -430,7 +430,7 @@ cargo run -p archivr-server -- ./archivr-server.toml
# Frontend (from frontend/) # Frontend (from frontend/)
bun install bun install
bun run dev # Vite dev server bun run dev # Vite dev server
bun run build # → crates/archivr-server/static/ bun run build # → crates/archivr-server/static/ (gitignored; nix build does this automatically)
# Nix # Nix
nix develop # dev shell nix develop # dev shell

View file

@ -121,6 +121,60 @@
--prefix PATH : ${lib.makeBinPath [ pkgs.python312 pkgs.ffmpeg ]} --prefix PATH : ${lib.makeBinPath [ pkgs.python312 pkgs.ffmpeg ]}
''; '';
}; };
# Frontend: per-system hash for the node_modules FOD.
# bun installs platform-specific native binaries (esbuild, rollup),
# so the hash differs between systems.
# To compute the hash for a new system, set its entry to
# "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" and run:
# nix build .#archivr-server 2>&1 | grep "got:"
# then paste the reported hash here.
frontendDepsHash =
{
"aarch64-darwin" = "sha256-QYmiCaORbrWPVaM9xXViCZChSxwObRCjlrM03zukjQ0=";
"x86_64-linux" = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
"aarch64-linux" = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
}
.${system} or "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
# FOD: fetch npm deps via bun. Network is allowed; output is hashed.
frontendDeps = pkgs.stdenv.mkDerivation {
pname = "archivr-frontend-deps";
version = "0.1.0";
src = ./frontend;
nativeBuildInputs = [ pkgs.bun ];
buildPhase = ''
export HOME=$TMPDIR
bun install --frozen-lockfile
'';
installPhase = ''
cp -r node_modules $out
'';
outputHash = frontendDepsHash;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
# Build the Vite bundle using the pre-fetched node_modules.
# Source files in frontend/src/ are jj-tracked and flow through automatically;
# only the deps hash (above) needs updating when bun.lock/package.json changes.
frontendStatic = pkgs.stdenv.mkDerivation {
pname = "archivr-frontend-static";
version = "0.1.0";
src = ./frontend;
nativeBuildInputs = [ pkgs.nodejs ];
buildPhase = ''
export HOME=$TMPDIR
export BABEL_CACHE_PATH=$TMPDIR/babel-cache
cp -r ${frontendDeps} node_modules
chmod -R u+w node_modules
node node_modules/vite/bin/vite.js build --outDir dist
'';
installPhase = ''
cp -r dist $out
'';
dontFixup = true;
};
version = "0.1.0"; version = "0.1.0";
src = pkgs.lib.cleanSource ./.; src = pkgs.lib.cleanSource ./.;
cargoLock = { cargoLock = {
@ -206,7 +260,7 @@
cp ${archivr_server_unwrapped}/bin/archivr-server $out/libexec/archivr-server/archivr-server cp ${archivr_server_unwrapped}/bin/archivr-server $out/libexec/archivr-server/archivr-server
cp ${./vendor/twitter/scrape_user_tweet_contents.py} $out/libexec/archivr-server/scrape_user_tweet_contents.py cp ${./vendor/twitter/scrape_user_tweet_contents.py} $out/libexec/archivr-server/scrape_user_tweet_contents.py
chmod +x $out/libexec/archivr-server/scrape_user_tweet_contents.py chmod +x $out/libexec/archivr-server/scrape_user_tweet_contents.py
cp -r ${./crates/archivr-server/static}/* $out/share/archivr-server/static/ cp -r ${frontendStatic}/* $out/share/archivr-server/static/
makeWrapper $out/libexec/archivr-server/archivr-server $out/bin/archivr-server \ makeWrapper $out/libexec/archivr-server/archivr-server $out/bin/archivr-server \
--set ARCHIVR_STATIC_DIR $out/share/archivr-server/static \ --set ARCHIVR_STATIC_DIR $out/share/archivr-server/static \
--set ARCHIVR_YT_DLP ${ytDlp}/bin/yt-dlp \ --set ARCHIVR_YT_DLP ${ytDlp}/bin/yt-dlp \