Skip to content

Changelog

Version 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_tag rebuilds the Service table to drop the typeTag column, 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 the Service table to drop the now-unused typeTag column, 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-deps on 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 a viewer token) read decrypted secrets; confirmed against a live instance. Reveal is now admin-only, with the requireAdmin guard 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/me now splits the all-roles secrets:read (key/metadata listing) from a new admin-only secrets:reveal scope. The allowSecretReveal toggle and neverReveal flag 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 viewer service-account token, set BRIDGEPORT_URL/BRIDGEPORT_TOKEN, and run example read-only curls, across .env.example, docs/operations/troubleshooting.md, and a CLAUDE.md pointer with a read-only guardrail for coding agents. -----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgEyiv4hf6iBgr34ICjN6HnEP/vs Yr31eNU5HhdkQaYd4AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQPlms3dhn0NjE+dgV27VB+qobyazAcBxCGnwpMkuF/K3BTPpVWb/m13mpYavPyzfeA Y4Wkxty1DkXBY9Rd3NCAI= -----END SSH SIGNATURE-----