- Add ANTHROPIC_API_KEY env passthrough in docker-compose.yml - Add astro telemetry and devToolbar disable settings - Update CLAUDE.md with deployment notes
104 lines
3.8 KiB
Markdown
104 lines
3.8 KiB
Markdown
# SpiceBook
|
|
|
|
Notebook interface for SPICE circuit simulation.
|
|
|
|
- **Frontend**: Astro 5 SSR + React 19 islands (`frontend/`)
|
|
- **Backend**: FastAPI + ngspice (`backend/`)
|
|
- **Production**: https://spicebook.warehack.ing
|
|
- **Repo**: git.supported.systems:warehack.ing/spicebook.git
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Local dev (Docker)
|
|
make dev
|
|
# Local site: https://spicebook.l.warehack.ing (via caddy-docker-proxy)
|
|
# API docs: https://spicebook.l.warehack.ing/docs
|
|
|
|
# Local dev (no Docker)
|
|
cd backend && uv run uvicorn spicebook.main:app --host 0.0.0.0 --port 8099 --reload
|
|
cd frontend && npm run dev -- --host 0.0.0.0 --port 4322
|
|
```
|
|
|
|
### Local vs Production domains
|
|
|
|
| Environment | Domain | `.env` setting |
|
|
|-------------|--------|----------------|
|
|
| Local dev | `spicebook.l.warehack.ing` | `SPICEBOOK_DOMAIN=spicebook.l.warehack.ing` |
|
|
| Production | `spicebook.warehack.ing` | `SPICEBOOK_DOMAIN=spicebook.warehack.ing` |
|
|
|
|
The `.env` on the dev machine should use `spicebook.l.warehack.ing` — the `.l.` subdomain resolves locally. Using the production domain (`spicebook.warehack.ing`) will route requests to the remote production server, not the local containers.
|
|
|
|
## Deployment to Production
|
|
|
|
Production runs on `warehack.ing` (149.28.126.25) behind caddy-docker-proxy.
|
|
|
|
```bash
|
|
# 1. Push changes
|
|
git push origin main
|
|
|
|
# 2. SSH to production server
|
|
ssh -A warehack-ing@warehack.ing
|
|
|
|
# 3. Pull and rebuild
|
|
cd ~/spicebook
|
|
git pull origin main
|
|
make prod
|
|
|
|
# 4. Verify
|
|
docker compose -f docker-compose.yml -f docker-compose.prod.yml logs --tail=20
|
|
```
|
|
|
|
### Production environment notes
|
|
|
|
- `.env` on the production server is NOT tracked in git — edit it directly on the server when adding new env vars
|
|
- `BACKEND_INTERNAL_URL=http://backend:8000` must be set for SSR server-side fetches (frontend talks to backend over Docker network)
|
|
- `notebooks/user/` must be world-writable (chmod 777) because the backend runs as non-root user `spicebook` but the bind mount is owned by `warehack-ing`
|
|
- The `@resvg/resvg-js` native binary requires `node:20-slim` (Debian glibc) — Alpine won't work
|
|
- OG image font comes from `@fontsource/inter` in `node_modules`, not a separate font file
|
|
|
|
### Caddy routing
|
|
|
|
Caddy routes `/api/*`, `/health`, `/docs`, `/openapi.json` to the backend (port 8000). Everything else goes to the frontend (port 4321). No Caddy config changes needed for new frontend routes — they're caught by the frontend's SSR handler.
|
|
|
|
## Architecture
|
|
|
|
### SSR Data Flow
|
|
|
|
Notebook pages fetch metadata server-side via `server-api.ts`:
|
|
- `fetchNotebookMeta(id)` calls `BACKEND_INTERNAL_URL/api/notebooks/{id}` with a 5s timeout
|
|
- Title, engine, and tags populate SEO meta tags at render time
|
|
- If the backend is unreachable, pages degrade to generic metadata
|
|
|
|
### OG Image Pipeline
|
|
|
|
`/og/[id].png` and `/og/default.png` are SSR API routes that:
|
|
1. Fetch notebook metadata from the backend (same internal URL)
|
|
2. Render JSX layout with Satori (SVG)
|
|
3. Rasterize to PNG with @resvg/resvg-js (native Rust NAPI binding)
|
|
4. Return with cache headers (1h client / 24h CDN for notebooks, 24h/7d for default)
|
|
|
|
### Key Environment Variables
|
|
|
|
| Variable | Where | Purpose |
|
|
|----------|-------|---------|
|
|
| `PUBLIC_API_URL` | Build-time (Vite) | Client-side API base URL. Empty string = same origin (prod) |
|
|
| `BACKEND_INTERNAL_URL` | Runtime (process.env) | SSR server-to-server API URL over Docker network |
|
|
| `SPICEBOOK_DOMAIN` | Docker labels | Caddy reverse proxy domain |
|
|
| `CORS_EXTRA_ORIGINS` | Backend | Additional CORS origins for embed framing |
|
|
|
|
## Build & Test
|
|
|
|
```bash
|
|
cd frontend
|
|
npx astro check # TypeScript type checking
|
|
npm run build # Full SSR build
|
|
```
|
|
|
|
## Style Guide
|
|
|
|
- Date-based versioning (YYYY.MM.DD)
|
|
- Dark theme: slate-950 background, slate-200 text
|
|
- Icons: astro-icon with lucide set (server-rendered SVGs, zero JS)
|
|
- React components use `client:load` for interactive islands
|