100 Commits
Author SHA1 Message Date
twothatITandClaude Sonnet 5 a5988af6a3 fix(update): stop blocking event loop during rebuild + fix infinite spinner
The update endpoint ran the entire git pull + docker build (up to 10 min)
synchronously inside the request handler, blocking the whole server for
everyone while it ran. Separately, the frontend spinner was only hidden on
error, never on success, so it spun forever even when the update worked.

- Run the update in a background thread; the request returns immediately
- Add GET /settings/update/status for progress polling (backup/pull/build/restart)
- Frontend polls status, then waits for the app to come back after the
  container restart, and shows a clear done/timeout message instead of an
  endless spinner

Co-Authored-By: Claude Sonnet 5 <[email protected]>
v1.1.2
2026-07-23 15:09:42 +02:00
twothatITandClaude Sonnet 5 c5189d88fe perf(npm): cache NPM JWT instead of re-authenticating on every API call
Every NPM helper (proxy host create/update/delete, streams, certs) did a
fresh POST /api/tokens login before its actual request, adding an avoidable
round-trip to every proxy/stream operation.

- Cache the JWT per (api_url, email), sized from its 'exp' claim
- Transparently re-authenticate and retry once on a 401 (e.g. after an NPM
  restart invalidates a cached token), so a stale cache entry can't cause a
  hard failure

Co-Authored-By: Claude Sonnet 5 <[email protected]>
v1.1.1
2026-07-23 14:51:23 +02:00
twothatITandClaude Sonnet 5 ac843da4ca perf(monitoring): stop blocking event loop with synchronous Docker calls
Customer search and detail loads were intermittently slow because every
customer-table render (including each search keystroke) triggered
/monitoring/customers/local-update-status, which looped synchronously over
all customers doing blocking `docker inspect` subprocess calls on the event
loop — stalling all other in-flight requests, including search itself.

- Offload per-service image/container inspection to the thread pool and run
  checks concurrently instead of sequentially (image_service, docker_service)
- Reuse a single Docker SDK client instead of reconnecting per customer
- Cache local-update-status results for 20s since the underlying data only
  changes after an image pull, not on every keystroke
- Parallelize /monitoring/customers container status lookups

Co-Authored-By: Claude Sonnet 5 <[email protected]>
v1.1.0
2026-07-23 14:44:56 +02:00
twothatITandClaude Sonnet 4.6 f6b7eb2dae fix(npm): add gRPC read/send timeouts to proxy host location blocks
Adds grpc_read_timeout 3600s and grpc_send_timeout 3600s to both
ManagementService and SignalExchange location blocks to prevent
long-lived gRPC connections from being dropped by Nginx.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
v1.0.0
2026-05-06 12:01:14 +02:00
twothatITandClaude Sonnet 4.6 8ede0f0a3c fix(deploy): fix redeploy button broken by JSON.stringify double quotes
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.5
2026-03-10 22:13:23 +01:00
twothatITandClaude Sonnet 4.6 8040973227 fix(deploy): fix redeploy button broken by JSON.stringify double quotes
JSON.stringify('Name') produces "Name" with double quotes which breaks
the onclick attribute. Use data-customer-name attribute instead and
read it via this.dataset.customerName to avoid quoting issues.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-10 22:13:06 +01:00
twothatITandClaude Sonnet 4.6 3cdc82f919 fix(deploy): show customer name in redeploy modal instead of ID
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.4
2026-03-10 22:08:35 +01:00
twothatITandClaude Sonnet 4.6 40595fc381 fix(deploy): show customer name in redeploy modal instead of ID
The modal was showing '#2' instead of the customer name when opened
from the customer detail view, because the dashboard table row was
not visible. Now the name is passed directly from the button's onclick
context where data.name is already available.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-10 22:08:17 +01:00
twothatITandClaude Sonnet 4.6 9ace554427 fix(cache): bust browser cache for JS and i18n files after updates
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.3
2026-03-10 21:57:36 +01:00
twothatITandClaude Sonnet 4.6 f48c851ef0 fix(cache): bust browser cache for JS and i18n files after updates
After a container update, browsers serve stale app.js and lang/*.json
from cache, causing old UI code and missing translations to appear.

- serve_index() now reads the git commit hash and injects ?v=COMMIT into
  all static asset URLs (app.js, i18n.js, styles.css) in index.html
- window.STATIC_VERSION is injected into the page so i18n.js can append
  the same version to lang/*.json fetch calls
- index.html itself is served with Cache-Control: no-cache so the browser
  always revalidates it and picks up new asset URLs on next load

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-10 21:57:18 +01:00
twothatITandClaude Sonnet 4.6 7d694c62bd feat(deploy): redeploy dialog with keep-data or fresh-deploy option
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.2
2026-03-10 21:34:26 +01:00
twothatITandClaude Sonnet 4.6 d1bb6a633e feat(deploy): redeploy dialog with keep-data or fresh-deploy option
Add a confirmation modal when clicking Redeploy that lets the user choose:
- Keep Data: containers are recreated without wiping the instance directory.
  NetBird database, peer configs, and encryption keys are preserved.
- Fresh Deploy: full undeploy (removes all data) then redeploy from scratch.

Backend changes:
- POST /customers/{id}/deploy accepts keep_data query param (default false)
- When keep_data=true, undeploy_customer is skipped entirely
- deploy_customer now reuses existing npm_proxy_id/stream_id when the
  deployment record is still present (avoids duplicate NPM proxy entries)
- DNS record creation is skipped on keep_data redeploy (already exists)

Frontend changes:
- customerAction('deploy') opens the redeploy modal instead of calling API
- showRedeployModal(id) shows the two-option confirmation card dialog
- confirmRedeploy(keepData) calls the API with the correct parameter
- i18n keys added in en.json and de.json

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-10 21:34:12 +01:00
twothatITandClaude Sonnet 4.6 b39a502257 fix(images): use Docker Registry v2 API for correct digest comparison
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.1
2026-03-02 15:15:22 +01:00
twothatITandClaude Sonnet 4.6 dee07d7b8e fix(images): use Docker Registry v2 API for correct digest comparison
The Docker Hub REST API returns per-platform manifest digests, while
docker image inspect RepoDigests stores the manifest list digest.
These two values never match, causing update_available to always be
True even after a fresh pull.

Fix: use registry-1.docker.io/v2/{name}/manifests/{tag} with anonymous
auth and read the Docker-Content-Digest response header, which is the
exact same digest that docker pull stores in RepoDigests.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-02 15:15:05 +01:00
twothatITandClaude Sonnet 4.6 351caec893 docs: update README with all current features and correct settings
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-25 08:34:29 +01:00
twothatITandClaude Sonnet 4.6 dd04408dc2 docs: update README with all current features and correct settings
- Add NetBird Container Updates section (digest check, pull, bulk update)
- Add update indicators, dark mode, LDAP/AD, Windows DNS to features
- Correct Settings table: add all tabs, remove incorrect Monitoring entry
- Split Docker Images tab out of System tab
- Add sudo install note for fresh Debian minimal
- Rewrite Updating NetBird Images section with new UI-based workflow
- Add new monitoring/image API endpoints to API docs

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-25 08:33:20 +01:00
twothatITandClaude Sonnet 4.6 6373722c2b chore(release): merge unstable → main for beta-1.0
Promotes alpha-1.25 to beta-1.0 (stable branch).

Highlights:
- NetBird container update management (check / pull / update per customer + bulk)
- Visual update badges on dashboard and customer detail
- Dark mode toggle with localStorage persistence
- User role management for Azure AD / LDAP users
- Branding logo persistence across updates (Docker volume)
- Favicon, NPM stream removal, MFA (TOTP)
- LDAP / Active Directory and Azure AD SSO
- Windows DNS integration
- Settings restructure and Git branch dropdown

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
beta-1.0
2026-02-24 21:58:24 +01:00
twothatITandClaude Sonnet 4.6 27c8e4889c feat(updates): visual update indicators, progress feedback, settings pull
- Dashboard: update badge (orange) injected lazily into customer Status cell
  after table renders via GET /monitoring/customers/local-update-status
  (local-only Docker inspect, no Hub call on every page load)
- Customer detail Deployment tab: "Update Images" button with spinner,
  shows success/error inline without page reload
- Monitoring Update All: now synchronous + sequential (one customer at a
  time), shows live spinner + per-customer results table on completion
- Settings > Docker Images: "Pull from Docker Hub" button with spinner
  and inline status message
- /monitoring/customers/local-update-status: new lightweight endpoint
  (no network, pure local Docker inspect)
- /monitoring/customers/update-all: removed BackgroundTasks, now awaits
  each customer sequentially and returns detailed per-customer results

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.25
2026-02-24 21:25:33 +01:00
twothatITandClaude Sonnet 4.6 848ead0b2c feat(updates): NetBird container image update management
- New image_service.py: Docker Hub digest check (no pull), local digest/ID
  comparison, pull_all_images, per-customer container image status, and
  update_customer_containers (docker compose up -d, data-safe)
- Monitoring endpoints: GET /images/check (hub vs local + per-customer
  needs_update), POST /images/pull (background), POST /customers/update-all
- Deployment endpoint: POST /{id}/update-images (single-customer update)
- Monitoring page: "NetBird Container Updates" card with Check / Pull / Update
  All buttons; image status table and per-customer update table with inline
  update buttons
- i18n: added keys in en.json and de.json

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.24
2026-02-24 21:01:56 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 796824c400 feat(users): allow role assignment for Azure AD and LDAP users
- Backend: add admin-only guard + role validation to PUT /users/{id}
- Backend: prevent admins from changing their own role
- Frontend: role toggle button (person-check / person-dash) per user row
- Frontend: admin badge green, viewer badge secondary, ldap badge blue
- i18n: add makeAdmin / makeViewer translations (de + en)

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.23
2026-02-24 20:27:54 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 8103fffcb8 fix(docker): persist branding uploads across container rebuilds
Mount ./data/uploads into /app/static/uploads so uploaded logos
survive image rebuilds during the update process.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.22
2026-02-24 20:19:22 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 13408225b4 feat(ui): add dark mode toggle to navbar
Uses Bootstrap 5.3 native data-bs-theme with localStorage persistence.
Inline script in <head> prevents flash on page load.
Moon/sun icon in top-right navbar switches between light and dark.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.21
2026-02-24 20:08:18 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 0f77aaa176 fix(deploy): remove NPM stream creation on customer deploy/undeploy
STUN/TURN UDP relay no longer requires NPM stream entries.
NetBird uses rels:// WebSocket relay via NPM proxy host instead.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.20
2026-02-24 19:42:12 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 0bc7c0ba9f feat(ui): add SVG favicon for NetBird MSP Appliance
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.19
2026-02-24 16:54:21 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 27428b69a0 fix(netbird): query customer before use in stop/start/restart
In stop_customer, start_customer and restart_customer the local variable
'customer' was referenced on the instance_dir line before it was assigned
(it was only queried after the docker compose call). This caused an
UnboundLocalError (HTTP 500) on every stop/start/restart action.

Fix: move the customer query to the top of each function alongside the
deployment and config queries.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.18
2026-02-24 11:12:17 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 582f92eec4 fix(update): add git safe.directory and fetch --tags after pull
- Register SOURCE_DIR as git safe.directory before pulling so the
  process (root inside container) can access repos owned by a host user
- Run 'git fetch --tags' after pull so git describe always finds the
  latest tag for version.json — git pull does not reliably fetch all tags

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.17
2026-02-24 10:58:02 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 1d27226b6f fix(update): detect compose project name at runtime instead of hardcoding
The project name was hardcoded as 'netbirdmsp-appliance' but Docker Compose
derives the project name from the install directory name ('netbird-msp').
This caused Phase A to build an image under the wrong project name and
Phase B to start the replacement container under a mismatched project,
leaving the old container running indefinitely.

Fix: read the 'com.docker.compose.project' label from the running container
at update time. Both Phase A (build) and Phase B (docker compose up) now
use the detected project name. Falls back to SOURCE_DIR basename if the
inspect fails.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.16
2026-02-24 10:51:25 +01:00
Sascha Lustenberger | techlan gmbhandClaude Sonnet 4.6 c70dc33f67 fix(caddy): route relay WebSocket traffic to relay container
Add /relay* location block to Caddyfile template so that NetBird relay
WebSocket connections (rels://) are correctly forwarded to the relay
container instead of falling through to the dashboard handler.

Without this fix, all relay WebSocket connections silently hit the
dashboard container, causing STUN/relay connectivity failures for all
deployed NetBird instances.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
alpha-1.15
2026-02-24 10:31:08 +01:00
Sascha Lustenberger | techlan gmbh fb264bf7c6 Fix: Add grpc_pass to NPM advanced_config for Management and Signal endpoints alpha-1.14 2026-02-23 14:49:43 +01:00
Sascha Lustenberger | techlan gmbh f3304b90c8 Fix: correctly detect update when current version is unknown alpha-1.13 2026-02-23 13:11:04 +01:00
Sascha Lustenberger | techlan gmbh cda916f2af Fix: display dynamic version on login and use subdomain for customer directories instead of kunde{id} alpha-1.12 2026-02-23 12:58:39 +01:00
twothatIT c3ab7a5a67 fix(api): correct extraction of commit date from gitea branches api alpha-1.11 2026-02-22 22:57:07 +01:00
twothatIT b955e4f464 feat(ui): settings menu restructure, git branch dropdown, and repo cleanup alpha-1.10 2026-02-22 21:29:30 +01:00
twothatIT 831564762b feat(ui): clean vertical settings menu and improved version formatting alpha-1.9 2026-02-22 16:07:08 +01:00
twothatIT 3f177a6993 fix(updater): add --rm to helper container to remove it after use 2026-02-22 15:58:18 +01:00
twothatIT ea4afbd6ca alpha-1.8: final test with privileged alpha-1.8 2026-02-22 15:49:44 +01:00
twothatIT 95ec6765c1 fix(updater): add --privileged to helper container to bypass user namespace restrictions alpha-1.7 2026-02-22 15:46:09 +01:00
twothatIT c40b7d3bc6 alpha-1.7: final test 2026-02-22 15:39:18 +01:00
twothatIT 525b056b91 fix(updater): add :z flag to docker volumes for SELinux alpha-1.6 2026-02-22 15:33:42 +01:00
twothatIT 6bc11d4c5e alpha-1.6: test final update 2026-02-22 15:25:50 +01:00
twothatIT e0aa51bac3 fix(updater): remove log redirection from helper to avoid nonexistent dir error alpha-1.5 2026-02-22 15:22:43 +01:00
twothatIT 94d0b989d0 alpha-1.5: trigger update 2026-02-22 15:16:20 +01:00
twothatIT 2780b065d2 fix(updater): add force-recreate and logging to helper container alpha-1.4 2026-02-22 15:14:23 +01:00
twothatIT ef691a4308 alpha-1.4: test helper-container update 2026-02-22 14:51:43 +01:00
twothatIT 0fe68cc6df fix: use helper container for self-update (survives container restart) alpha-1.3 2026-02-22 14:50:00 +01:00
twothatIT 314393d61a alpha-1.3: update test 2026-02-22 14:42:53 +01:00
twothatIT a9fc549cec fix: correct docker compose project name and target only app service for update alpha-1.2 2026-02-22 14:40:07 +01:00
twothatIT 41bbd6676b alpha-1.2: test update button 2026-02-22 14:34:46 +01:00
twothatIT fc9589b6f9 fix: trigger_update setzt GIT_TAG/GIT_COMMIT env vars für docker compose rebuild alpha-1.1 2026-02-22 14:32:08 +01:00
twothatIT 6d2251bcf5 alpha-1.1: Login-Page Version-Marker hinzugefügt 2026-02-22 14:25:44 +01:00