Skip to content
Upgrade to Bridge v2

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 example bridge_bridge-data.
  • The tenant subdomain and the broker pool token from the v1 .env file.
  • The scripts and script parameters on each Bridge profile.
  • Your own TLS certificate and key, if v1 used TLS_CERT_FILE and TLS_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-keyscan result.
  • 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:

terminal
docker compose down

Archive the volume. Replace bridge_bridge-data with your volume name:

terminal
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.

bridge.yaml
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: true

Set 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:

bridge.yaml
    cert_path: /etc/britive-bridge/certs/api-cert.pem
    key_path: /etc/britive-bridge/certs/api-key.pem

Write 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.

docker-compose.yaml
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:

docker-compose.yaml
      - ./certs:/etc/britive-bridge/certs:ro

Create the .env file

Generate the encryption key:

terminal
openssl rand -base64 32

Write the key and the two broker values from v1 into .env, next to the Compose file:

.env
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:

terminal
docker compose up --no-start

Copy the recordings from the v1 volume and give them to the v2 user, 102:103. Replace bridge_bridge-data with your volume name:

terminal
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:

terminal
docker compose run --rm --no-deps --entrypoint ls bridge -ln /data/recordings

Replace 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 permissionv2 scripts
adminBridge/permissions/admin
sshLinux/permissions/temp-user-bridge
rdpWindows/permissions/temp-user-bridge
vnc, telnet, k8sexecNone. 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.

  1. Delete every --admin-token and --cluster-token option. The helper script rejects them as unknown options.
  2. Delete every --api-url option and every line that sets BRIDGE_API_URL or BRIDGE_ADMIN_TOKEN. v2 configures the helper script for you.
  3. Replace any curl call to the Bridge API with the helper script. v2 does not accept the v1 admin token.
  4. Set the profile’s BRIDGE_URL parameter to the host name.
  5. Return the launch link without the token:
checkout.sh
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:

terminal
docker compose up -d

On its first start, Bridge imports the v1 recordings. Then continue with Verify.

Verify

Check the API

The health endpoint returns {"status":"ok"}:

terminal
curl -sk https://localhost/api/health

Open 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:

terminal
docker compose down

In the v1 folder, start v1:

terminal
docker compose up -d

v1 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.

  1. Deploy a new stack. Follow AWS Deployment (ECS Fargate).
  2. Before the first start of the new stack, copy recordings from 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.
  3. Start the new stack. The orchestrator imports the v1 recordings on its first start.
  4. Point the BRIDGE_URL script parameter at the new load balancer.
  5. Replace the profile scripts as described in Replace the Profile Scripts.
  6. Verify as described in Verify.
  7. 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

SymptomCauseFix
v1 recordings are missing from the session listBridge started before the recordings were in the volume.Start over.
Bridge exits with failed to import legacy recording metadata and no such columnv2 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 supportedThe 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 connectionsssh.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-tokenThe script passes a v1 option.Delete the option.
The Admin console returns unauthorizedThe 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:

terminal
docker compose down --volumes

This 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 ssh command that works only with ssh.native.enabled: true and port 22 published.
  • Operations covers backups, health checks, and later upgrades.
Last updated on