Upgrade to Bridge v2
Overview
This guide moves a single-container Bridge v1.0.x deployment to v2. You deploy v2 beside the stopped v1 container, copy the recordings into it, and replace the scripts on your Britive Bridge profiles. The v1 volume stays untouched, so rollback means starting v1 again.
v2 has no in-place upgrade. It needs PostgreSQL, a new configuration file, an encryption key, and new checkout scripts. Recordings carry over. Active checkouts do not, so users check out again after the upgrade.
If you run the v1 ECS Fargate template, read Upgrade an ECS Fargate deployment first.
Before You Begin
Collect these items before the maintenance window:
- The name of the v1 data volume. Run
docker volume ls. Compose adds the project directory as a prefix, for examplebridge_bridge-data. - The tenant subdomain and the broker pool token from the v1
.envfile. - The scripts and script parameters on each Bridge profile.
- Your own TLS certificate and key, if v1 used
TLS_CERT_FILEandTLS_KEY_FILE. Without them, v2 generates a new self-signed certificate. - The public host key of each SSH target. Read each key from the target or from your inventory. Do not trust an unauthenticated
ssh-keyscanresult. - For each RDP target, a certificate that names the target host and that the Bridge image trusts. See RDP.
- A maintenance window. Stopping v1 ends every active session.
Prepare v2
Stop v1 and back up its volume
Stop the v1 container:
docker compose downArchive the volume. Replace bridge_bridge-data with your volume name:
docker run --rm -v bridge_bridge-data:/data:ro -v "$PWD":/backup alpine \
tar czf /backup/bridge-data-v1.tgz -C /data .Keep the archive until users have completed a full checkout, session, and checkin on v2.
Write the configuration file
Create a new folder for v2. In it, save this file as bridge.yaml. It turns on the browser protocols that v1 offered and turns on Britive login.
server:
listen: 443
log_level: info
tls:
enabled: true
datastore:
host: postgres
port: 5432
user: bridge
password: bridge
name: bridge
sslmode: disable # matches the postgres service in the Compose file
recording:
output_dir: /data/recordings
auth:
types: [britive]
britive:
tenant: your-tenant # for example acme
ssh:
idle_timeout: 30m
allow_insecure_host_key: true # transition only. See the scripts step.
native:
enabled: false
browser:
enabled: true
telnet:
idle_timeout: 30m
browser:
enabled: true
rdp:
idle_timeout: 30m
browser:
enabled: true
vnc:
idle_timeout: 30m
browser:
enabled: true
k8s_exec:
idle_timeout: 30m
browser:
enabled: trueSet server.auth.britive.tenant to your tenant.
Keep Britive login on. v2 opens the Admin console and recording review only to a user who has logged in. If you set server.auth.types: [], users can still open sessions, but nobody can review recordings.
If v1 used your own certificate, copy the files into a certs folder next to bridge.yaml. Then add these lines under server.tls:
cert_path: /etc/britive-bridge/certs/api-cert.pem
key_path: /etc/britive-bridge/certs/api-key.pemWrite the Compose file
Save this file as docker-compose.yaml in the same folder. It is the published single-server Compose file with two changes: the broker variables are set, and native SSH is not published.
services:
export:
image: britive/bridge:v2.3.1
restart: unless-stopped
environment:
BRIDGE_ROLE: export
user: "102:103"
network_mode: none
read_only: true
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
mem_limit: "1g"
cpus: "1"
tmpfs:
- /tmp:size=1g,mode=1777
volumes:
- recordings:/data/recordings
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: bridge
POSTGRES_PASSWORD: bridge
POSTGRES_DB: bridge
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "bridge"]
interval: 5s
retries: 10
bridge:
image: britive/bridge:v2.3.1
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
BRIDGE_CONFIG: /etc/britive-bridge/config.yaml
BRIDGE_ENCRYPTION_KEY_B64: "${BRIDGE_ENCRYPTION_KEY_B64:?set BRIDGE_ENCRYPTION_KEY_B64 in .env}"
BRITIVE_BROKER_TENANT_SUBDOMAIN: "${BRITIVE_BROKER_TENANT_SUBDOMAIN}"
BRITIVE_BROKER_AUTH_TOKEN: "${BRITIVE_BROKER_AUTH_TOKEN}"
volumes:
- ./bridge.yaml:/etc/britive-bridge/config.yaml:ro
- recordings:/data/recordings
ports:
- "443:443"
volumes:
pgdata:
recordings:If you copied your own certificate in the previous step, add this line under bridge.volumes:
- ./certs:/etc/britive-bridge/certs:roCreate the .env file
Generate the encryption key:
openssl rand -base64 32Write the key and the two broker values from v1 into .env, next to the Compose file:
BRIDGE_ENCRYPTION_KEY_B64=<the generated key>
BRITIVE_BROKER_TENANT_SUBDOMAIN=<tenant subdomain>
BRITIVE_BROKER_AUTH_TOKEN=<broker pool token>Store a copy of the encryption key outside the host. Bridge encrypts stored checkout credentials with it. If you lose the key, Bridge cannot read any stored checkout.
With the broker token set, Bridge fetches its license from your tenant and renews it. Without a license, Bridge runs only browser sessions and turns off live view, session control, and downloads. See Licensing.
Copy the recordings
Copy the recordings before the first v2 start. Bridge imports v1 recordings once, on its first start against an empty database.
Create the v2 volumes without starting any service:
docker compose up --no-startCopy the recordings from the v1 volume and give them to the v2 user, 102:103. Replace bridge_bridge-data with your volume name:
docker compose run --rm --no-deps -v bridge_bridge-data:/v1:ro \
--entrypoint sh bridge -c \
'cp -a /v1/recordings/. /data/recordings/ && chown -R 102:103 /data/recordings'Check the copy. The output lists date folders, such as 2026, and metadata.db:
docker compose run --rm --no-deps --entrypoint ls bridge -ln /data/recordingsReplace the Profile Scripts
v1 scripts fail against v2 at the API call. Replace each script on your Bridge profiles before users check out.
Use the published v2 scripts
The v2 scripts are in britive/access-broker-examples. Each folder’s README lists the script parameters that the profile needs.
| v1 permission | v2 scripts |
|---|---|
admin | Bridge/permissions/admin |
ssh | Linux/permissions/temp-user-bridge |
rdp | Windows/permissions/temp-user-bridge |
vnc, telnet, k8sexec | None. Edit your v1 script in the next step. |
In the v2 scripts, the BRIDGE_URL parameter is a host name, such as bridge.example.com, not a URL.
The SSH and RDP scripts sign users in with a Bridge password. Add BRIDGE_AUTH_PASSWORD to those permissions.
The published SSH script does not send target_ssh_host_key. Keep ssh.allow_insecure_host_key: true while you use it unmodified. To turn verification on, add the field to the script’s payload and set the setting to false.
Edit the remaining scripts
For VNC, Telnet, and Kubernetes exec, edit your v1 script. Keep the helper path, /opt/britive-broker/scripts/bridge.sh.
- Delete every
--admin-tokenand--cluster-tokenoption. The helper script rejects them as unknown options. - Delete every
--api-urloption and every line that setsBRIDGE_API_URLorBRIDGE_ADMIN_TOKEN. v2 configures the helper script for you. - Replace any
curlcall to the Bridge API with the helper script. v2 does not accept the v1 admin token. - Set the profile’s
BRIDGE_URLparameter to the host name. - Return the launch link without the token:
URL="https://${BRIDGE_URL}/connect?transaction_id=${TRANSACTION_ID}"The user logs in with Britive, and Bridge opens the session page for the checkout’s protocol. The other v1 checkout fields work as before. See the Payload reference.
Start v2
Start the stack:
docker compose up -dOn its first start, Bridge imports the v1 recordings. Then continue with Verify.
Verify
Check the API
The health endpoint returns {"status":"ok"}:
curl -sk https://localhost/api/healthOpen the Admin console
Check out the admin profile on your tenant and open the returned link. Log in with Britive. The session list opens, and the floating Admin button appears.
The admin checkout’s username must be the Britive identity the user logs in with. An admin checkout grants nothing to any other login.
Play a v1 recording
Open a v1 session in the session list and play its recording.
Run a new session
Check out a user profile, open the link, and connect. End the session. Confirm that the session list shows it with a recording.
Roll Back
Stop v2:
docker compose downIn the v1 folder, start v1:
docker compose up -dv1 reads its own volume, which the upgrade did not change. Checkouts created on v2 do not exist on v1.
Upgrade an ECS Fargate Deployment
You cannot update the v1 ecs-fargate.yaml stack to v2. v2 on AWS runs an orchestrator with session and proxy workers, and it needs an RDS or Aurora PostgreSQL database.
- Deploy a new stack. Follow AWS Deployment (ECS Fargate).
- Before the first start of the new stack, copy
recordingsfrom the v1 EFS file system to the new one. Use AWS DataSync or a one-off task. Set the owner of the copied files to 102:103. - Start the new stack. The orchestrator imports the v1 recordings on its first start.
- Point the
BRIDGE_URLscript parameter at the new load balancer. - Replace the profile scripts as described in Replace the Profile Scripts.
- Verify as described in Verify.
- Delete the v1 stack.
If you deployed the new stack into the v1 VPC, check its route tables and security groups before step 7. Deleting the v1 stack also deletes any NAT gateway, subnet, or security group that the v1 stack created.
Troubleshoot
| Symptom | Cause | Fix |
|---|---|---|
| v1 recordings are missing from the session list | Bridge started before the recordings were in the volume. | Start over. |
Bridge exits with failed to import legacy recording metadata and no such column | v2 cannot read that metadata.db. | Move metadata.db out of the recordings volume and start Bridge again. Bridge then imports each session from its metadata.json file. |
Checkout fails with protocol "admin" is no longer supported | The profile still runs the v1 admin script. | Use the v2 admin script. It sends "role": "admin". |
Checkout fails with target_ssh_host_key is required for verified SSH target connections | ssh.allow_insecure_host_key is false and the script sends no host key. | Add target_ssh_host_key to the script’s payload, or set the setting to true for the transition. |
The helper script prints error: unknown option: --admin-token | The script passes a v1 option. | Delete the option. |
The Admin console returns unauthorized | The login identity does not match the admin checkout’s username, or the checkout expired. | Check out the admin profile again and log in with the same identity. |
Start over
Bridge imports v1 recordings only on its first start against an empty database. To run the import again, remove the v2 database and start from the copy step.
Stop v2 and delete its volumes:
docker compose down --volumesThis deletes the v2 database and the copied recordings. It also deletes any checkouts created on v2. The v1 volume does not change.
Repeat Copy the recordings, then Start v2. Bridge fetches its license from your tenant again on start.
Next Steps
- Single-Server Deployment shows how to turn on native SSH. The v2 SSH script returns an
sshcommand that works only withssh.native.enabled: trueand port 22 published. - Operations covers backups, health checks, and later upgrades.