# NAS Tools Project ## Architecture - Synology DS224+ (x86_64, 18GB RAM), Tailscale IP: `100.78.131.124`, LAN: `192.168.31.221` - Docker: `/volume1/@appstore/ContainerManager/usr/bin/docker`, compose dirs: `/volume1/docker/*` - VPS Caddy (`161.33.182.109`, Tailscale: `100.109.198.126`): reverse proxy for `*.jimmygan.com` - Build VPS (server2, `158.101.140.85`, Tailscale: `100.70.115.1`): podman, fast network - NAS Caddy: port 8443 fallback only (SNI broken) ## Dashboard - Backend: Python FastAPI (`dashboard/backend/`) - Frontend: Svelte 5 + Tailwind CSS (`dashboard/frontend/`) - Svelte 5 runes: use `$state`, `$props`, `$bindable` (not legacy `export let`) - Sidebar categories: Main, Media, Tools (see `docs/architecture.md` for full layout) - New pages: create route in `src/routes/`, import in `App.svelte`, update `Sidebar.svelte` ## CI/CD Two workflows in `.gitea/workflows/`: - **deploy.yml** — main branch: tests → build → deploy to production - **deploy-dev.yml** — dev branch: tests → build → deploy to dev Two runners: - **VPS runner** (`vps` label on server2) — build + test jobs (podman) - **NAS runner** (`nas` label on DS224+) — deploy jobs (docker, host networking) ### Build flow 1. VPS builds Docker image + pushes to local registry `100.78.131.124:5501/` 2. Streams image to NAS: `podman save | gzip | ssh nasts "gunzip | docker load"` 3. NAS deploys: `docker compose up -d` ## Local Registry - Container: `registry-mirror` on NAS, port 5501 - Standalone mode (NOT Docker Hub proxy — blocked from China) - VPS pushes with `podman push --tls-verify=false` ## Authentication - **Gitea API Access:** Token stored in `~/.config/tea/config.yml` (user: `jimmy`) - **Gitea Token:** `aa8c20329040c56c079d2676318c6e33f14b221d` - **Project Secrets:** Gitea repo secrets: CI_TOKEN, CI_DB_PASSWORD, SECRET_KEY, ADMIN_PASSWORD_HASH, TRANSMISSION_USER, TRANSMISSION_PASS ## claude-dev CI Contract - Source in `claude-dev/` (Dockerfile, required-tools.txt, scripts/) - CI-first: update `claude-dev/*` in git, then push - Workflow: `.gitea/workflows/deploy-claude-dev-dev.yml` - Uses NAS runner with `DOCKER_BUILDKIT=0` - Immutable tag format: `claude-dev:dev--` - Runtime compose: `claude-dev/docker-compose.yml` - Rollback: run workflow with `rollback_image` using value from `/volume1/docker/claude-dev/previous-image.txt` ## Synology Quirks - No `crontab` — edit `/etc/crontab` with `sudo` + `printf`, restart crond - No `scp` subsystem — use `cat file | ssh ... 'cat > dest'` - ACLs override Unix perms — use `sudo chmod 777` + `synoacltool -enforce-inherit` - Tailscale userspace mode — cannot bind Docker ports to Tailscale IPs ## DNS - dnsmasq on NAS resolves `*.jimmygan.com` → `161.33.182.109` (Caddy VPS) - Tailscale split DNS: `jimmygan.com` → NAS (queries hit dnsmasq) ## Proxy API - URL: `https://www.bytecatcode.org` - Models: `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-haiku-4-5-20251001` ## Key Files - `docs/architecture.md` — full architecture reference - `docs/TESTING.md` — test patterns and conventions - `.gitea/workflows/deploy.yml` — main CI - `.gitea/workflows/deploy-dev.yml` — dev CI