Default all day-to-day work to gallery_dev and devgallery; add Cursor rule and update docs, env examples, and deploy guide for scheduled prod promotion.
5.6 KiB
Deploy Gallery on TrueNAS Scale
Production deployment for the Express API + built Vite SPA container. PostgreSQL stays on the host at 192.168.10.122:5432. Public URL: https://gallery.mysuperlab.netcraze.pro (Keenetic → TrueNAS :5173, protocol to device http).
Not for daily work. Develop on dev (gallery_dev, https://devgallery.mysuperlab.netcraze.pro). Use this guide when releasing to prod (~weekly): build/push image, sync data/images if needed, restart the TrueNAS app.
See also Documentation/environments.md.
Architecture
Browser (HTTPS)
→ Keenetic (KeenDNS, SSL termination)
→ gallery-web container on TrueNAS (:5173, HTTP)
→ PostgreSQL (192.168.10.122:5432) → gallery_prod
→ /mnt/BasePool/Applications/Gallery/data/images (volume)
→ SMB share Gallery → \\192.168.10.122\Gallery (image sync from dev PC)
Prerequisites
| Item | Notes |
|---|---|
| TrueNAS Scale 25.04+ | Apps → Custom App support |
| PostgreSQL | gallery_prod (dev: gallery_dev on same host) — split via pgAdmin script |
| Gitea registry | gitea.mysuperlab.netcraze.pro — image danilka/gallery-web:latest pushed before deploy |
| SMB share | Gallery at /mnt/BasePool/Applications/Gallery for images:sync-to-prod |
| Keenetic | gallery.mysuperlab.netcraze.pro → 192.168.10.122:5173, protocol http, Preserve Host ON |
If deploy fails with manifest unknown, the image is not in Gitea yet — complete §1 Build and push first.
1. Build and push image (dev machine)
Where: Dev PC — PowerShell as Administrator (LAN push hosts entry), Docker Desktop running
cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery
docker login gitea.mysuperlab.netcraze.pro
npm run docker:publish
Push only (already built): npm run docker:publish:push-only
Image: gitea.mysuperlab.netcraze.pro/danilka/gallery-web:latest
Gitea registry tokens
| Machine | Token scope |
|---|---|
| Build PC | write:package |
| TrueNAS pull | read:package |
Register on TrueNAS: Apps → Configuration → Sign in to a Docker registry — URL https://gitea.mysuperlab.netcraze.pro, username danilka (lowercase for registry).
Registry token URL fix
If docker push fails with internal HTTP token URL, set Gitea ROOT_URL to https://gitea.mysuperlab.netcraze.pro/ and restart Gitea. Full walkthrough: Drunkmeyou gitea-https-keenetic-npm-setup.md.
Offline fallback (no registry)
On dev PC: .\infra\docker\save-for-truenas.ps1 → copy gallery-web.tar via SMB Gallery share.
On TrueNAS shell: sudo bash truenas-load-image.sh /path/to/gallery-web.tar
In Custom App YAML: pull_policy: if_not_present, then redeploy.
2. Prepare TrueNAS storage
Where: TrueNAS — Shell, as root
mkdir -p /mnt/BasePool/Applications/Gallery/data/images/portraits
mkdir -p /mnt/BasePool/Applications/Gallery/data/images/paintings/thumbs
chown -R 1001:1001 /mnt/BasePool/Applications/Gallery
chmod -R u+rwX,g+rwX /mnt/BasePool/Applications/Gallery
Enable SMB share Gallery → /mnt/BasePool/Applications/Gallery (for image sync from dev PC).
3. Sync images (first deploy)
Where: Dev PC — PowerShell (normal), repo root
net use \\192.168.10.122\Gallery /user:YOUR_TRUENAS_USER
cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery
npm run images:sync-to-prod
UNC destination: \\192.168.10.122\Gallery\data\images
4. Install Custom App
Where: TrueNAS — Web UI
- Apps → Discover Apps → Custom App
- Paste
compose.truenas.yaml - Set
DB_PASSWORD(replaceYOUR_POSTGRES_PASSWORD) - Deploy → wait for gallery-web Running
5. Keenetic (production)
| Field | Value |
|---|---|
| Domain | gallery.mysuperlab.netcraze.pro |
| Upstream | 192.168.10.122:5173 |
| Protocol to device | http |
| Preserve Host | ON |
Wrong IP or https to device → 502 / 504 from Keenetic (Server: Web server).
6. Verify
Bypass Keenetic (should be instant JSON):
curl.exe -s http://192.168.10.122:5173/api/bounds
Public URL:
curl.exe -sk https://gallery.mysuperlab.netcraze.pro/api/bounds
Open https://gallery.mysuperlab.netcraze.pro/ — timeline and /images/paintings/... should load.
On TrueNAS shell: bash infra/docker/truenas-verify.sh
7. Update production
After code changes on dev PC:
npm run docker:publish
Restart gallery-web on TrueNAS (or rely on pull_policy: always).
Troubleshooting
| Issue | Fix |
|---|---|
manifest unknown |
Run npm run docker:publish first; or offline truenas-load-image.sh |
| 502 / 504 public URL | Keenetic → 192.168.10.122:5173, protocol http; verify LAN curl above |
| Container cannot reach Postgres | DB_HOST=192.168.10.122; extra_hosts in compose |
| Empty timeline | DB_NAME=gallery_prod; run pgAdmin split if still on legacy Gallery |
| Missing images | npm run images:sync-to-prod; check volume mount and chown 1001:1001 |
| Pull 401 | Gitea registry credentials on TrueNAS; read:package token |
| Push fails on dev PC | Gitea ROOT_URL HTTPS fix; use Admin PowerShell for LAN push |