heartwood every commit a ring

the root learns to name the fields it tends

e01d4f05 by Isaac Bythewood · 23 days ago

modified CLAUDE.md
@@ -28,12 +28,28 @@ There are no tests, linters, or build steps in this repo — it is pure configur## Architecture- **`dotfiles/`** — Terminal and editor config (bash, git, tmux, neovim). Neovim config is Lua-based with a custom statusline. These get COPYed into the container at build time.- **`containers/webdev/`** — Ubuntu 24.04 dev container running PostgreSQL 16 + Redis via supervisord. Includes Node 22 (yarn via corepack), Python 3 (pip + uv), and standard dev tools.- **`containers/webdev/`** — Ubuntu 24.04 dev container running PostgreSQL 16 + Redis via supervisord. Includes Node 22, Python 3 (pip + uv), Bun, Yarn (via corepack — still available for legacy repos, though all current projects use Bun), Docker-in-Docker, and standard dev tools (neovim, tmux, git, rsync, htop, nmap, etc.).- **`hosts/alpine/`** — Production server setup: Caddy reverse proxy (auto HTTPS), Docker Compose for services, Borg backups, UFW firewall, push-to-deploy via git hooks.## Deployed Projects`hosts/alpine/srv/projects.conf` is the single source of truth. Format per line:`name|port|github_repo|branch|has_data_dir|runs_migrations`. Current manifest:| Project | Port | Stack | Data dir | Migrations ||---|---|---|---|---|| `analytics` | 8000 | Django + Vite (Bun) + SQLite | yes | yes || `blog.bythewood.me` | 8100 | Flask (uv) + Vite (Bun) | no | no || `timelite` | 8200 | Next.js + Bun (local-only, no backend) | no | no || `isaacbythewood.com` | 8300 | Next.js + Bun (Pages Router, plain JS) | no | no || `status` | 8400 | Django + Vite (Bun) + SQLite | yes | yes || `darkfurrow.com` | 8500 | Flask (uv) | no | no |Update ports, repos, or flags by editing `projects.conf` and re-running the relevant provisioning step — every downstream artifact (Caddyfile routes, post-receive hooks, bootstrap script) is generated from this file.## How Deployment Works`hosts/alpine/srv/projects.conf` is the single source of truth for deployed projects. Each entry defines a project name, port, GitHub repo, and whether it needs data dirs or migrations. The bootstrap script creates bare git repos at `/srv/git/` with post-receive hooks that auto-deploy by pulling changes and running `docker compose up --build --detach`.`quickstart.sh` reads `projects.conf` and generates one bare repo under `/srv/git/<name>.git/` per project with a post-receive hook. Pushing to that remote triggers: `git pull`, `docker compose up --build --detach`, optional `manage.py migrate`, and a `borg` prune on hosts configured for backup. The Caddyfile proxies each project's subdomain to its bound port on `127.0.0.1`.## Conventions
modified README.md
@@ -31,11 +31,25 @@ taproot/            └── bootstrap.sh    clone all repos into a fresh code directory```## The projects it tendsEverything deployed lives in `hosts/alpine/srv/projects.conf`. The Caddyfile,port map, and post-receive hooks all grow from that single file.| Project | Port | What it is ||---|---|---|| [`analytics`](https://github.com/overshard/analytics) | 8000 | Self-hosted website analytics (Django, SQLite) || [`blog.bythewood.me`](https://github.com/overshard/blog.bythewood.me) | 8100 | Personal blog (Flask, markdown files) || [`timelite`](https://github.com/overshard/timelite) | 8200 | Local-only time tracker (Next.js, IndexedDB) || [`isaacbythewood.com`](https://github.com/overshard/isaacbythewood.com) | 8300 | Personal portfolio (Next.js) || [`status`](https://github.com/overshard/status) | 8400 | Uptime monitor & status page (Django, SQLite) || [`darkfurrow.com`](https://github.com/overshard/darkfurrow.com) | 8500 | Seasonal almanac (Flask) |## The containerAn Ubuntu-based development workstation with everything already in the ground:Python, Node, PostgreSQL, Redis, Docker, neovim, tmux, and Claude. Managed bysupervisord. Enter through tmux.Python (uv), Node, Bun, PostgreSQL, Redis, Docker, neovim, tmux, and Claude.Managed by supervisord. Enter through tmux.Build from the repo root so the dotfiles are in the build context: