Single-Server Deployment
In single-server mode, one container does everything: it serves the web app, listens for native connections, records sessions, and talks to your targets. It’s the simplest way to evaluate the Bridge or run it for a small team.
Single-server mode does not scale across machines or survive a host failure. For production, use the AWS or Kubernetes guide.
Overview
By the end of this guide you’ll have:
- A PostgreSQL database running in a container.
- The Bridge running in a container next to it.
- The web app reachable in your browser.
- SSH access to a target working through the Bridge.
We’ll use Docker Compose, a tool that runs several containers together from one file. If you can install Docker, you can follow this guide.
Before You Begin
You need:
- The Bridge container image - pulled automatically from Docker Hub
(
britive/bridge); nothing to build. - A Linux host (or a Mac/Windows machine) with Docker and the Docker
Compose plugin installed. Run
docker --versionanddocker compose versionto confirm. - About 2 GB of free memory for the containers.
What is a container? A container is a lightweight, self-contained package that includes the software and everything it needs to run. Docker is the tool that runs containers. You don’t install the Bridge onto your operating system - you run its container.
Step 1: Generate the Encryption Key
The Bridge encrypts the credentials it stores in the database. You must give it a random 32-byte key, encoded as text (base64). Generate one:
openssl rand -base64 32Copy the output (it looks like q7Fh2...=). You’ll put it in a .env file in
the next step so it’s kept out of the compose file itself.
Save this key somewhere safe and reuse the same key every time you start the Bridge. If you lose it or change it, the credentials already stored in your database can no longer be decrypted.
Step 2: Create the Configuration File
Create a folder for your deployment, and inside it a file named bridge.yaml.
This minimal example turns on browser SSH and native SSH, and points at
the PostgreSQL container we’ll start in the next step:
server:
listen: "443" # the web app + browser sessions
log_level: "info"
tls:
enabled: true # serve HTTPS with an auto-generated certificate
datastore: # PostgreSQL connection (the db service below)
host: "postgres"
port: 5432
user: "bridge"
password: "bridge"
name: "bridge"
sslmode: "disable"
recording:
output_dir: "/data/recordings"
auth:
types: ["britive"] # log in with your Britive tenant
britive:
tenant: "your-tenant" # subdomain only, e.g. "acme" — see /reference/finding-your-tenant
ssh:
native:
enabled: true
listen: "22"
browser:
enabled: true
idle_timeout: "30m"Replace your-tenant with your Britive tenant subdomain — see Finding Your Tenant Name. You can also use LDAP instead of
or alongside Britive - see Authentication.
A complete, fully commented reference of every option is available to download:
bridge.reference.yaml. You can also start
from this exact sample: bridge.single.yaml.
Step 3: Create the Compose File
In the same folder, create docker-compose.yaml. This runs PostgreSQL and the
Bridge together:
services:
postgres:
image: postgres:17-alpine
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:latest # pulled from Docker Hub
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
# Path to the config file inside the container
BRIDGE_CONFIG: /etc/britive-bridge/config.yaml
# Read from the .env file next to this compose file (see below). The :? makes
# `docker compose up` fail fast with a clear message if it isn't set.
BRIDGE_ENCRYPTION_KEY_B64: "${BRIDGE_ENCRYPTION_KEY_B64:?set BRIDGE_ENCRYPTION_KEY_B64 (openssl rand -base64 32) in .env}"
# Optional — Britive platform integration. The broker-pool token runs the
# co-located Britive broker (JIT checkout provisioning) AND enables automatic
# license retrieval + renewal. The broker creates checkouts against the Bridge
# admin API using BRIDGE_CLUSTER_TOKEN, so set it too when enabling the broker
# — otherwise checkouts fail with "cluster token required".
# BRITIVE_BROKER_AUTH_TOKEN: "your-broker-pool-token"
# BRITIVE_BROKER_TENANT_SUBDOMAIN: "your-tenant" # e.g. acme
# BRIDGE_CLUSTER_TOKEN: "generate-with: openssl rand -hex 32" # required when the broker is enabled
# BRIDGE_API_URL: "https://localhost:443" # this stack serves the API on 443 (broker default is :8080)
volumes:
- ./bridge.yaml:/etc/britive-bridge/config.yaml:ro
- recordings:/data/recordings
ports:
- "443:443" # web app (https://localhost)
- "22:22" # native SSH
volumes:
pgdata:
recordings:Put the key from Step 1 in a .env file in the same folder - Docker Compose
reads it automatically, so the key stays out of the compose file:
BRIDGE_ENCRYPTION_KEY_B64=<paste-your-key-here>Prefer to download these? Grab the ready-made
docker-compose.single.yaml and
bridge.single.yaml (rename it to
bridge.yaml), drop them in a folder, set your tenant in the config, and put your
encryption key in a .env file as shown above. The first time you start, Docker
pulls britive/bridge:latest from Docker Hub automatically.
Step 4: Start It
From your folder, run:
docker compose up -dThis downloads PostgreSQL, starts both containers, and runs the Bridge in the background. The first start takes a minute while the database initializes and the Bridge applies its schema.
Watch the logs to confirm it came up cleanly:
docker compose logs -f bridgeYou’re looking for lines showing the database connection succeeded, migrations
applied, and the server is listening. Press Ctrl+C to stop watching the logs
(the container keeps running).
Verify
1. Open the web app. Visit https://localhost/ in your browser. Because the
Bridge generated its own certificate, your browser will warn you the connection
isn’t trusted - that’s expected for a self-signed certificate. Accept the warning
to continue, and log in with your Britive tenant.
2. Check the API is healthy from the command line:
curl -k https://localhost/api/license/statusYou should get a JSON response (the -k flag tells curl to accept the
self-signed certificate).
3. Connect through the Bridge. Once you have a checkout for an SSH target, you can connect natively:
ssh -p 22 <your-checkout-user>@localhostTroubleshoot
| Symptom | Likely Cause | Fix |
|---|---|---|
| Bridge container restarts immediately | Database not reachable, or config invalid | Run docker compose logs bridge. Check the datastore settings match the postgres service, and that your YAML is valid. |
| “encryption key” error on startup | BRIDGE_ENCRYPTION_KEY_B64 missing or not valid base64 | Regenerate with openssl rand -base64 32 and paste the full value. |
| Can’t open the web app | Port already in use, or TLS confusion | Make sure nothing else uses port 443; try https:// (not http://). |
| Browser says the certificate is invalid | The Bridge uses a self-signed certificate | Expected in a trial. For production, put a load balancer or reverse proxy with a real certificate in front. |
| Login fails | Wrong tenant, or auth not configured | Confirm auth.britive.tenant; see Authentication. |
Next Steps
- Configure authentication
- Install and manage your license.
- Review protocols, recording, operations for the Admin console, upgrades, and backups.
- When you’re ready for production, move to AWS or Kubernetes.