144 lines
5.6 KiB
Markdown
144 lines
5.6 KiB
Markdown
# 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 |
|