taproot
mirrorThe dotfiles and containers I use to set up a machine for development, one container to write code in and another that runs a local coding model on the desktop's GPU.
alpine-linuxcaddydevelopment-environmentdockerdotfileshomelabinfrastructureneovimserver-configurationtmux
1---
2name: rust
3description: Work on the Rust axum projects in this workspace (blog.bythewood.me, plus the archived analytics-rust, status-rust, finance-rust, repos-rust and darkfurrow.com). Invoke when building, running, editing, or debugging any of these single-binary axum + Vite + SQLite apps. Covers the shared architecture, dev commands, and the gotchas that bite (Jinja URL escaping, embedded Typst PDF, the Vite manifest). Always read the project's own note in code/memory/projects/<name>.md first for project-specific detail.
4---
5
6# Rust axum projects
7
8Six apps share one architecture: a single axum binary with a Vite-built frontend and an
9embedded SQLite database. Only `blog.bythewood.me` is still active, and `analytics-rust`,
10`status-rust`, `finance-rust`, `repos-rust` and `darkfurrow.com` were archived on 2026-08-26
11and their local checkouts have no git remotes. **Before editing one, read its living note**
12`~/code/memory/projects/<name>.md` (analytics-rust, status-rust, finance-rust, blog,
13darkfurrow, repos-rust):
14that note is the authoritative per-project guidance (env vars, deploy, quirks) that used
15to live in a per-project CLAUDE.md.
16
17This skill is instructions only. There is no LSP here (we dropped the rust-analyzer-lsp
18plugin). Rely on `cargo check`/`cargo build` for diagnostics.
19
20## Shared shape
21
22- Tiny `src/main.rs` entry, and `src/app.rs` builds `AppState` + the `Router`. Per-feature
23 route modules live under `src/routes/`.
24- Helpers: `src/render.rs` (template render), `src/middleware.rs` (request log + 404),
25 `src/templates.rs` (minijinja env + filters).
26- Frontend in `frontend/` (Vite) builds to `dist/`, served at `/static/` with
27 content-hashed filenames. The binary reads `dist/.vite/manifest.json` to resolve the
28 hashed names in templates. **If assets 404, the manifest or `dist/` is stale rebuild
29 the frontend.**
30- minijinja 2 for Jinja2-faithful templates, tower-cookies for signed sessions, sqlx 0.8
31 on SQLite (WAL, `synchronous=NORMAL`, busy timeout, foreign keys on) with migrations
32 auto-applied on boot.
33
34## Dev commands (all projects)
35
36- `make run` (default): installs frontend deps if needed, then runs Vite watch +
37 `cargo run` concurrently on **port 8000**. Visit `http://localhost:8000`.
38- `make build`: Vite assets + release binary at `target/release/<name>` plus `dist/`.
39- `make start`: run the release binary (after `make build`).
40- `make clean`: `cargo clean` plus removing `dist/`, `node_modules/`, the SQLite db.
41- `sudo docker build .`: production image. **No tests, no linters** in any project.
42- Rust deps via `cargo` (`Cargo.toml`/`Cargo.lock`), JS deps via `bun` from `frontend/`.
43- Local builds need `pkg-config` + OpenSSL headers, which the Docker build supplies.
44
45## Gotchas
46
47- **Jinja URL escaping.** All projects ship a Jinja2-faithful HTML formatter in
48 `src/templates.rs` so `/` is not escaped to `/` in URLs. If URLs render mangled,
49 that filter is the place to look do not work around it in templates.
50- **PDF reports** are rendered in-process via embedded Typst (`typst` + `typst-pdf` +
51 `typst-kit` 0.14), no chromium subprocess. `status` still bundles chromium, but only
52 for Lighthouse audits, not PDF. Alpine runtimes must install body/mono/fallback fonts
53 (jetbrains-mono, dejavu, liberation, fontconfig) so Typst finds fonts.
54- **Ports.** Every container listens on 8000 internally in dev and prod. In prod no host
55 ports are published, and Caddy reverse-proxies by container name on 8000.
56
57## Deploy
58
59`git push server master` triggers a post-receive hook: `docker compose up --build
60--detach`, then reattaches the container to the shared `bythewood-edge` Docker network.
61Manifest: `~/code/taproot/hosts/alpine/srv/projects.conf`.