Windows desktop client for the LAN chat app. The UI is the same Angular build as the website, served locally on 127.0.0.1 with a proxy to your server’s nginx on port 4200.
- Bundled UI (
resources/app-uiin the installer):http://127.0.0.1:<fixed-port>/(stable across restarts; configured viaCHATEANDO_BUNDLED_PORT, default17321) - API / SignalR: relative
/apiand/hubs→ local proxy → backend base URL (default LANhttp://<server>:5095) - Auto-updates: packaged builds poll
http://<server>:5095/desktop-updates/latest.yml(served directly by the backend API from a persistent volume). Updates download silently; the nav shows Restart and update when ready. - Do not point the proxy at
:5095unless you run the API without nginx; production Docker exposes the API only under/api/on:4200.
- Node.js + npm (same as the monorepo)
- Windows 10/11 (installer target)
- Server reachable on the LAN (
docker compose upon the host) - Docker Desktop (for publishing updates into the frontend container)
- Code signing certificate for production releases (
CSC_LINK,CSC_KEY_PASSWORD)
From the repo root, with Docker running and the backend service up:
cd desktop
copy .env.build.example .env.build
# Set CHATEANDO_HOST=192.168.x.xnpm run release:unsigned # patch bump (0.1.0 → 0.1.1)
npm run release:unsigned:minor
npm run release:unsigned:majorBuilds without a cert, publishes to the backend updates folder, and bakes allowUnsignedUpdates: true so clients accept unsigned auto-updates.
$env:CSC_LINK = "C:\path\to\cert.pfx"
$env:CSC_KEY_PASSWORD = "your-password"
npm run release
npm run release:minor
npm run release:majorThis single command:
- Refuses if the git working tree is dirty
- Bumps
desktop/package.jsonvianpm version(creates commit +desktop-v*tag) - Builds the Angular Electron bundle
- Builds and signs the NSIS installer +
latest.yml+.blockmap docker cps artifacts into the running backend container at/app/desktop-updates/(persisted in thedesktop_updates_backendnamed volume)- Prints a
curlURL to verify
Verify the feed:
npm run release:verify| Variable | Required | Description |
|---|---|---|
CHATEANDO_HOST |
yes (via .env.build) |
LAN server IP used to derive default web/API/update URLs |
CHATEANDO_API_PORT |
optional | Backend API/update feed port (default 5095) |
CSC_LINK |
yes for npm run release |
Path to code-signing .pfx |
CSC_KEY_PASSWORD |
yes for npm run release |
Certificate password |
CHATEANDO_UPDATE_FEED_URL |
optional | Override feed URL (must end with /desktop-updates/) |
CHATEANDO_BACKEND_CONTAINER |
optional | Override only if not using the compose backend service |
CHATEANDO_UPDATE_KEEP |
optional | Keep last N installer versions in the volume (default 3) |
Republish a previous build under a new higher version (downgrades are disabled). To restore an older latest.yml in an emergency:
docker exec <backend-container> ls /app/desktop-updates/
# copy a previous latest.yml + matching .exe back, or re-run npm run release after restoring filesWarning: docker compose down -v deletes the desktop_updates_backend volume and all published installers.
-
Copy and edit the build env:
cd desktop copy .env.build.example .env.build # Set CHATEANDO_HOST=192.168.x.x (your server IP, no path) -
Build the Angular app for Electron:
cd ..\frontend npm run build:electron
-
Build and package the desktop app:
cd ..\desktop npm install npm run dist:unsigned
Output:
desktop/release/Chateando Setup *.exe
CHATEANDO_HOST is baked into dist/build-defaults.json at build time (preferBundled: true, updateFeedUrl). End users do not enter the server URL.
With Docker on localhost:4200:
cd frontend
npm run build:electron
cd ..\desktop
npm install
npm run build
npm startIf no .env.build exists, the app may open the website at http://localhost:4200 when it is reachable; otherwise it uses the bundled UI and frontend/proxy.conf.json target (http://localhost:5095 for ng serve-style API). For Docker, set in PowerShell before npm start:
$env:CHATEANDO_SERVER_URL = "http://localhost:4200"
$env:CHATEANDO_USE_BUNDLED = "1"
npm startAuto-updater is disabled in dev (npm start) and in web launch mode.
Desktop updates now come from backend (:5095 by default). If desktop Check updates returns 404:
- Confirm
.env.buildhas the rightCHATEANDO_HOSTandCHATEANDO_API_PORT. - Confirm backend is serving the feed:
curl.exe -I http://<server>:5095/desktop-updates/latest.ymldocker exec <backend-container> ls /app/desktop-updates/
- Republish:
npm run release:unsignedthennpm run release:verify.
If docker compose runs in Ubuntu WSL, docker ps in PowerShell may only show unrelated containers (e.g. chateando-frontend on port 5173). The Chateando stack (chateando-backend-1 on 5095) lives in WSL.
npm run release:unsigned auto-detects WSL Docker (distro Ubuntu; override with CHATEANDO_DOCKER_WSL=Ubuntu). Keep the stack running in WSL:
cd /mnt/c/Users/.../chateando
docker compose up -d backendOr run the full release from WSL in desktop/. Do not point CHATEANDO_BACKEND_CONTAINER at the port-5173 dev stack.
- X on the window hides to the system tray (app keeps running).
- Tray → Open Chateando or click the icon to show the window.
- Tray → Quit fully exits.
- Restart and update sets
isQuitting, destroys the window/tray, then runs the silent installer.
Nginx only proxies /api/. In server logs you should see:
POST /api/auth/login
If you see POST /auth/login with 405, the request missed the /api prefix. Rebuild desktop and frontend after code changes; use port 4200 as the proxy target.
| Script | Description |
|---|---|
npm run build |
Compile TypeScript + build-defaults.json |
npm start |
Build + run Electron (dev; updater disabled) |
npm run dist |
Windows NSIS installer (signed if CSC_LINK set) |
npm run dist:unsigned |
Windows NSIS installer without signing |
npm run release |
Bump version, build, sign, publish to backend container updates path |
npm run release:unsigned |
Bump version, build unsigned, publish to backend feed (LAN auto-update) |
npm run release:verify |
Check latest.yml is reachable and not HTML |
LAN internal rollout can use npm run release:unsigned (no cert). Clients must be installed from a build that includes allowUnsignedUpdates in build-defaults.json (set automatically when CHATEANDO_HOST is in .env.build).
Optional production signing: CSC_LINK + CSC_KEY_PASSWORD with npm run release. For a one-off unsigned installer only (no publish), use npm run dist:unsigned.
NSIS is configured for silent per-user updates (oneClick: true, perMachine: false). Existing per-machine installs must be uninstalled once before switching.
- Install an older packaged
.exeon two LAN clients (notnpm start). - Run
npm run releaseon the build/docker host. - Confirm
npm run release:verifypasses. - Within ~1 minute of opening/restoring the desktop app, confirm silent download (nav shows percentage).
- When ready, click Restart and update — app fully quits (no tray leftover) and restarts on the new version.
- Confirm web app shows no updater UI.
- Confirm read-state badges survive the update.