Compare commits

..

3 Commits

Author SHA1 Message Date
will 915c441170 Add README
Deploy / deploy (push) Successful in 1m2s
Explains what vu is and how to develop and run it in production, without referencing reground.org's specific infrastructure.
2026-08-16 06:30:00 -04:00
will 5c0664081b Add a generic production docker-compose.yml
Lets someone outside Reground's infra run vu standalone: builds the image and exposes it on localhost:8080, independent of the reground.org-specific compose config that joins an external network with no published port.
2026-08-16 06:29:56 -04:00
will 2c7ab3419d Ignore CLAUDE.md, MEMORY.md, and .claude/
These are Claude Code working files, not project documentation meant to ship in the repo.
2026-08-16 06:29:52 -04:00
3 changed files with 86 additions and 0 deletions
+4
View File
@@ -2,3 +2,7 @@ node_modules
dist
dev-dist
*.local
CLAUDE.md
MEMORY.md
.claude/
+72
View File
@@ -0,0 +1,72 @@
# vu
A static, offline-first PWA for praying the Divine Office — Matins, Lauds, Prime, Terce, Sext,
None, Vespers, and Compline — in bilingual Latin/English, for any given date.
This isn't a reconstruction of any single historical breviary. It's a personal design that
draws on several historical sources without reproducing any one of them exactly: hour
structure chiefly from the Monastic Tridentinum (1617), precedence/rubrics from Divino
Afflatu, and a calendar merged from both the Tridentine 1906 and Divino Afflatu calendars,
with more generous handling of commemorations and octaves than any one historical rite used.
See `CLAUDE.md` (gitignored, not shipped in this repo) or the project's own notes for the full
rationale if you're extending it.
There's no backend and no database — everything is a pre-built static bundle, and the app is
designed to keep working fully offline once it's been loaded once.
## Development
Requires Node.js (developed against Node 20+).
```sh
npm install
npm run dev # start the Vite dev server
npm run build # type-check (tsc --noEmit) and produce a production build in dist/
npm run preview # serve the production build locally
npm test # run the test suite (vitest)
```
Run a single test file or a subset by name:
```sh
npx vitest run tests/hours/vespers.test.ts
npx vitest run -t "some test name"
```
## Running in production
The app is entirely static once built, so "running it" just means serving `dist/` — any static
file host works, as long as it falls back to `index.html` for unknown paths (the app does its
own client-side routing for URLs like `/2026-08-09/prime`).
### Docker
A `Dockerfile` builds the static bundle with Node and serves it with Caddy:
```sh
docker build -t vu .
docker run -p 8080:80 vu
```
Or with Docker Compose (`docker-compose.yml` is included):
```sh
docker compose up -d --build
```
This serves the app on `http://localhost:8080`. Put a reverse proxy/TLS terminator in front of
it for a real deployment; the container itself just listens on port 80 internally and has no
configuration, secrets, or external dependencies.
### Without Docker
Any static file server works — build the app, then serve `dist/` with SPA-style fallback
routing. For example, with Caddy directly:
```sh
npm run build
caddy file-server --root dist --listen :8080
```
(For a real deployment you'll want a fallback rule so unknown paths resolve to `index.html`
see the `Caddyfile` in this repo for the pattern.)
+10
View File
@@ -0,0 +1,10 @@
# Generic production compose file — builds the static bundle and serves it
# with Caddy on port 8080. Not tied to any particular host's network/proxy
# setup; put a reverse proxy or TLS terminator in front of it as needed.
services:
vu:
build: .
container_name: vu
restart: unless-stopped
ports:
- "8080:80"