b52986fed5
Running python3 -m venv venv over an existing cached venv recreates the absolute symlinks and pyvenv.cfg paths so Python resolves to the current system's python3 binary. Without this, cp -a preserves stale symlinks from the cache source, causing venv/bin/python to resolve to /usr/bin/python3 (system, not venv) and pytest not found. Also switch validation to use python3 to match Ubuntu 24.04 convention.
3.5 KiB
3.5 KiB
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/* - Caddy VPS (
161.33.182.109, Tailscale:100.109.198.126): reverse proxy fornas.jimmygan.com→ NAS:4000,music.jimmygan.com→ NAS:4533 - Build VPS (server2,
158.101.140.85, Tailscale:100.70.115.1): podman, fast network for pulling images
Dashboard
- Backend: Python FastAPI (
dashboard/backend/) - Frontend: Svelte 5 + Tailwind CSS (
dashboard/frontend/) - Svelte 5 runes: use
$state,$props,$bindable(not legacyexport let) - Sidebar: categorized as Main (Overview, Docker, Files, Terminal), Media (Navidrome, Jellyfin, Audiobookshelf, Immich), Tools (OpenClaw, Repos, Gitea Web, Stirling PDF, Vaultwarden, Speedtest)
- New pages: create route in
src/routes/, import inApp.svelte, add to appropriate category inSidebar.svelte
Authentication
-
Gitea API Access: Use a dedicated
claude-ci-botuser with a Personal Access Token (PAT). -
Secret Management: Store the PAT in an environment variable
GITEA_TOKEN. Avoid hardcoding paths to secret files. -
Project Secrets: Keep sensitive configurations (like the PAT) in a local
.envfile that is ignored by git. -
Build images on VPS (server2) to avoid NAS HDD I/O saturation:
- Build on VPS with Podman
- Stream image to NAS:
podman save <image> | ssh nasts "/volume1/@appstore/ContainerManager/usr/bin/docker load" - Deploy:
git pushtriggers Gitea Actions CI (builds on VPS, transfers, thendocker compose up) — do NOT manually restart
-
CI workflows are in
.gitea/workflows/in this repo
claude-dev CI Contract
- Source package lives in
claude-dev/(Dockerfile,required-tools.txt, and smoke scripts underclaude-dev/scripts/) - CI-first only: update
claude-dev/*in git, then push; do not do ad-hoc local image rebuild/redeploy for normal changes - Required capabilities are declared in
claude-dev/required-tools.txt; adding tools must update this file and related smoke checks - Build/deploy gate (
.gitea/workflows/deploy-claude-dev-dev.yml) uses NAS runner withDOCKER_BUILDKIT=0, then runs:- tools smoke (
smoke-tools.sh) - network smoke (
smoke-network.sh) - auth/mount smoke (
smoke-auth.shwith required runtime mounts)
- tools smoke (
- Deployment only happens after smoke pass, using immutable tag format
claude-dev:dev-<timestamp>-<sha> - Runtime compose definition is
claude-dev/docker-compose.yml; CI syncs it to/volume1/docker/claude-dev/docker-compose.yml - Runtime requirements preserved:
network_mode: host,/volume1/reposmount,/root/.claudemount,/root/.claude.jsonmount,/root/.gitea_tokenmount - Rollback: run workflow manually with
rollback_image(for example the value in/volume1/docker/claude-dev/previous-image.txt) to redeploy a known-good immutable tag via CI
Synology Quirks
- No
crontab— edit/etc/crontabwithsudo+printf, restart crond - No
scpsubsystem — usecat file | ssh ... 'cat > dest' - ACLs override Unix perms — use
sudo chmod 777+synoacltool -enforce-inheritfor bind mounts
DNS
- dnsmasq on NAS resolves
*.jimmygan.com→161.33.182.109(Caddy VPS) - Tailscale split DNS:
jimmygan.com→ NAS (queries hit dnsmasq) - All paths (LAN, Tailscale, public) route through Caddy for TLS
Proxy API
- URL:
https://www.bytecatcode.org - Models:
claude-opus-4-6,claude-sonnet-4-6,claude-haiku-4-5-20251001(no date-suffixed names)