v2.0.1
What's new
BridgePort 2.0.1 is a maintenance release that hardens 2.0. It fixes a concurrent deploy race that was failing deploys and leaving ghost services behind, repairs multi-host monitoring charts, cold-start list pages, and the container logs modal, and closes a secret-disclosure security hole where read-only tokens could reveal secret values. It also resolves the confusing dual "type" fields from 2.0 by consolidating onto the admin-managed Service Type, and seeds eight new built-in service types.
Schema changes apply automatically on container start — the single migration in this release finishes the type consolidation by dropping the now-unused column, with no data loss and no manual steps.
Heads-up before upgrading
Skip this unless you used the free-form service Type field added in 2.0.
Service "type" consolidated onto the Service Type dropdown (#187)
2.0 shipped two overlapping "type" concepts — the admin-managed Service Type dropdown and a separate free-form Type text field (typeTag) — and only the free-form one powered the Services-list filters, which was confusing and broke type filtering for some services. 2.0.1 removes the free-form field and consolidates everything onto the Service Type dropdown, which now drives the filter chips, the "No type" chip, and the ?type= URL param.
- The migration
20260529130549_remove_service_type_tagrebuilds theServicetable to drop thetypeTagcolumn, preserving every other column — the only data lost is the removed free-form type strings. - To get filtering back: define types under
/admin/service-types, then assign them in the Configure Service dialog. - Until a service has a Service Type assigned, it shows as "Generic" / "No type".
Database migrations
One migration, applied automatically on container start — no manual steps.
20260529130549_remove_service_type_tag— rebuilds theServicetable to drop the now-unusedtypeTagcolumn, copying every other column across (no data loss beyond the removed free-form type strings). Completes the Service Type consolidation above. (#187)
Fixes
Concurrent compose-up race produced failed deploys and ghost services (#186)
The most impactful fix in this release. Two services attached to the same docker-compose.yml with auto-update enabled could deploy concurrently, where one service's depends_on cascaded into recreating the other's container mid-deploy — failing both deploys and leaving an orphaned container that discovery then materialized as a ghost service.
--no-depson single-service force-recreate (both v2 and v1 paths) stops a deploy from cascade-recreating dependencies owned by their own BridgePort service.- A new per-
(server, composePath)in-process keyed mutex serializes deploys touching the same compose file on the same server.
Multi-host monitoring charts dropped all but one series (#185)
On the Services and Servers monitoring pages, the CPU/Memory/Network charts rendered only one entity when an environment spanned multiple hosts, even though the table below listed them all — downsampling was collapsing staggered-timestamp series to null. Each row now falls back to its own most recent sample within the bucket, so every series stays populated.
List pages flashed an empty state on cold start (#184)
The Services, Servers, Databases, Container Images, and Config Files pages could briefly show "no results" before the environment resolved. The paginated fetch now treats a not-yet-ready fetch as pending and renders a skeleton, and Layout gained a bounded retry with backoff so a transient cold-start failure can't strand a page on a skeleton.
Logs modal opened scrolled to the oldest entry (#191)
The container logs modal opened at the top (oldest line), making recent logs look missing. It now pins to the bottom on open, matching docker logs, while paging back to older entries still preserves scroll position.
Security
- Read-only tokens could reveal secret values (#190) —
GET /api/secrets/:id/value, which decrypts and returns secret plaintext, had no role check, so the global read-method exemption let any authenticated principal (including aviewertoken) read decrypted secrets; confirmed against a live instance. Reveal is now admin-only, with therequireAdminguard running before the secret lookup so no plaintext can leak for operators or viewers. The UI hides the reveal control for non-admins, and/api/auth/menow splits the all-rolessecrets:read(key/metadata listing) from a new admin-onlysecrets:revealscope. TheallowSecretRevealtoggle andneverRevealflag remain as additional gates.
Features
Eight new built-in service types (#188)
Ships ready-to-use service-type definitions on top of the existing django, nodejs, and generic, each with genuinely useful exec commands:
- FastAPI — python shell, pip list, alembic upgrade/revision
- Flask — flask shell/routes, db upgrade, python repl
- Caddy — version, validate, reload, fmt, list-modules
- Nginx — config test, reload, version
- Celery — status, inspect active/scheduled/stats
- Keycloak — version, show-config (read-only
kc.sh) - Redis — redis-cli, ping, info, dbsize
- PostgreSQL — psql, list databases, version
They appear automatically on the next deploy via syncPlugins(); admin-customized types are left untouched and only missing commands are added — no manual step, no migration.
Documentation
- Read-only API access for live-instance debugging (#189) — documents how to mint a minimally-scoped
viewerservice-account token, setBRIDGEPORT_URL/BRIDGEPORT_TOKEN, and run example read-onlycurls, across.env.example,docs/operations/troubleshooting.md, and aCLAUDE.mdpointer with a read-only guardrail for coding agents.
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgEyiv4hf6iBgr34ICjN6HnEP/vs
Yr31eNU5HhdkQaYd4AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQPlms3dhn0NjE+dgV27VB+qobyazAcBxCGnwpMkuF/K3BTPpVWb/m13mpYavPyzfeA
Y4Wkxty1DkXBY9Rd3NCAI=
-----END SSH SIGNATURE-----