# NAS Tools — Architecture & Operations ## Overview NAS Dashboard is a web UI for managing a Synology DS224+ NAS and its ecosystem of services. It runs as a Docker container on the NAS with a FastAPI backend + Svelte 5 frontend. ## Architecture ``` Browser → VPS Caddy (161.33.182.109, port 443) → Tailscale → NAS Caddy (port 8443, fallback only) → NAS Dashboard (port 4000) ``` DNS: `*.jimmygan.com` → VPS Caddy → Tailscale → NAS services. ## Services ### Media | Service | URL | Port | Description | |---------|-----|------|-------------| | Navidrome | music.jimmygan.com | 4533 | Music streaming | | Jellyfin | media.jimmygan.com | 8097 | Media server | | Audiobookshelf | books.jimmygan.com | 13378 | Audiobooks & podcasts | | Immich | photos.jimmygan.com | 2283 | Photo/video backup | | t-youtube | yt.jimmygan.com | 8001 | YouTube subscription reader | | Transmission | (sidebar route) | 9091 | BitTorrent client | ### Tools | Service | URL | Description | |---------|-----|-------------| | Gitea | git.jimmygan.com | Git hosting + CI (Gitea Actions) | | LiteLLM | (dashboard route) | LLM proxy | | OPC | (dashboard route) | Kanban + agents | | n8n | n8n.jimmygan.com | Workflow automation | | Vaultwarden | vault.jimmygan.com | Password manager | | Hermes | hermes-agent.nousresearch.com/docs | AI Agent docs | ## CI/CD (Gitea Actions) ### Workflows - **deploy.yml** — Main branch: tests → build → deploy to production - **deploy-dev.yml** — Dev branch: tests → build → deploy to dev ### Runners - **VPS runner** (`vps` label) — server2 (Oracle Tokyo, 158.101.140.85). Used for build + test jobs. Uses podman. - **NAS runner** (`nas` label) — DS224+. Used for deploy jobs. Uses Docker via `/volume1/@appstore/ContainerManager/usr/bin/docker`. Runs with `nas:host` label (host networking). ### Build & Deploy Flow 1. VPS runner builds Docker image 2. Pushes to local registry: `100.78.131.124:5501/nas-dashboard:latest` (podman push --tls-verify=false) 3. Streams image to NAS via SSH pipe: `podman save | gzip | ssh nasts "gunzip | docker load"` 4. NAS runner deploys: `docker compose up -d` ### CI Speed Notes - Build is the bottleneck (~12 min first run due to npm ci + Vite build) - npm ci is cached between runs (node_modules saved to disk on VPS) - pip is cached between runs - Registry push enables future layer caching - Synology Docker daemon doesn't support `--tls-verify=false` for pulls; SSH pipe used instead ### Recent CI Fixes (July 2026) | Fix | Date | Description | |-----|------|-------------| | Checkout URL | Jul 8 | Changed from `gitea:3000` to `127.0.0.1:3300` (NAS host networking) | | TRANSMISSION_USER/PASS | Jul 8 | Added missing env vars to deploy step | | Gzip transfer | Jul 8 | Added gzip compression to SSH pipe | | Local registry | Jul 9 | Build pushes to local registry for layer caching | | NAS runner crash | Jul 8 | `.runner` address changed from `gitea:3000` to `127.0.0.1:3300` | ## Local Registry Registry container: `registry-mirror` on NAS, port 5501. - Standalone mode (NOT Docker Hub proxy — Hub is blocked from China) - Listens on `0.0.0.0:5501` - Images pushed by VPS CI, pulled by NAS fallback via SSH pipe - API: `http://100.78.131.124:5501/v2/` ## Dashboard Sidebar Layout ### Main Overview, LiteLLM, OPC, Files, Terminal, Security ### Media Navidrome, Jellyfin, Audiobookshelf, Immich, t-youtube, Media Management, Transmission ### Tools Hermes, Chat Digest, Code Sessions, Repos, Gitea Web, Stirling PDF, Vaultwarden, n8n, Speedtest All external links use clean HTTPS URLs (no `:8443` port). ## Cmd+K Palette Press `⌘K` (Mac) or `Ctrl+K` to fuzzy-search all sidebar items. New in July 2026. ## NAS 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` - Docker at `/volume1/@appstore/ContainerManager/usr/bin/docker` - Tailscale userspace mode — cannot bind to Tailscale IP directly in Docker ## Docker Networks ### NAS Dashboard Networks | Network | Type | Used By | Purpose | |---|---|---|---| | `internal` | compose-defined | docker-socket-proxy, dashboard | Internal communication between dashboard containers | | `nas-dashboard_internal` | external (pre-created) | docker-socket-proxy, dashboard, dashboard-dev | Shared internal network for dashboard services | | `gitea_gitea` | external | dashboard, dashboard-dev | Connect dashboard to Gitea container | Note: `internal` network is redundant — both services are also on `nas-dashboard_internal`. Consider removing `internal` and consolidating to `nas-dashboard_internal` only. ### Full NAS Network Inventory (all services) | Network | Service | |---|---| | `gitea_gitea` | Gitea | | `nas-dashboard_internal` | NAS Dashboard | | `internal` | NAS Dashboard (compose-defined) | | `authelia_auth` | Authelia | | `immich_immich` | Immich | | `jellyfin_default` | Jellyfin | | `audiobookshelf_default` | Audiobookshelf | | `calibre-web_default` | Calibre-Web | | `navidrome_default` | Navidrome | | `vaultwarden_default` | Vaultwarden | | `stirling-pdf_default` | Stirling PDF | | `n8n_default` | n8n | | `paperless_paperless` | Paperless | | `t-youtube_default` | t-youtube | | `watchtower_default` | Watchtower | | `dnsmasq_default` | DNS proxy | | `openclaw_default` | OpenClaw | | `openconnector_default` | OpenConnector | | `registry-mirror_default` | Registry mirror | | `speedtest_default` | Speedtest | | `metube_default` | MeTube | | `pixman_default` | Pixman | | `tmp_default` | Temporary services | | `bridge` | Docker default | | `host` | Docker host mode | | `none` | No networking |