BridgeLink Quick Start Guide Docker
For New Installations of BridgeLink 26.9.0
About This Guide
BridgeLink is Innovar Healthcare's integration platform. It moves messages between the systems in your organization and lets you build, run and watch those connections, called channels, from a web browser.
The steps here take one Linux host running Docker from an empty folder to a running BridgeLink 26.9.0 server, its database and WebAdmin.
An image is a packaged copy of a program and everything it needs to run. A container is one running copy of an image. Docker Compose starts several containers together from one settings file.
If you would like a hand with any part of the install, Innovar Healthcare's professional services team can help with as much or as little of it as you want.
What You Run
| Container | What it is | Runs as | Port |
|---|---|---|---|
bl | The BridgeLink server, with Java already inside the image | A non-root user inside the container | 8443 (HTTPS) |
postgres | The database BridgeLink keeps its channels, messages, events, users and settings in. You can point BridgeLink at an existing database server instead. | The database image's own user | Not published outside Docker |
webadmin | The browser-based tool you use to manage BridgeLink, in its own container | A non-root user inside the container | 8444 (HTTPS) |
Open port 8443 on the BridgeLink server to other machines only if WebAdmin runs on another machine or other programs call the BridgeLink API. Channels that listen for connections, such as MLLP or HTTP listeners, need their own ports opened. Port 8080 is BridgeLink's plain-HTTP port; nothing in this guide uses it, so keep it closed to other machines.
The Compose file in Setting Up the Deployment already publishes 8443 on every interface of the Docker host, and Docker-published ports bypass host firewalls such as ufw. WebAdmin reaches BridgeLink over the Docker network and does not need it. To keep 8443 local to the Docker host, change "8443:8443" to "127.0.0.1:8443:8443", and use localhost in step 9 of Replace the BridgeLink Server Certificate. A channel that listens for connections also needs its port added under ports: for bl.
With Docker there is no installer to run and no archive to unpack: each image already holds the software and everything it needs. Your choices are which image variant to use and the settings you pass in.
Requirements
- A Linux host, on
linux/amd64orlinux/arm64, with Docker Engine and the Docker Compose plugin. The plugin is version 2 of Compose, which you run asdocker compose(with a space, notdocker-compose). To install both, follow Docker's instructions athttps://docs.docker.com/engine/install/. - Permission to run
dockercommands. See Run Docker Without Root below. - Internet access to Docker Hub, where the BridgeLink images are published
sudorights on the host, to set folder ownership- To replace the BridgeLink server certificate (Replacing the Certificates):
keytoolfrom a Java 17 or 21 runtime on the host - A current browser for WebAdmin: Chrome, Edge or Firefox 120 or later, or Safari 17 or later
Run Docker Without Root
On a new Linux host, the first docker command fails with permission denied while trying to connect to the docker API at unix:///var/run/docker.sock. Your account is not allowed to use Docker yet. You have two ways to fix that:
- Add your account to the
dockergroup, then sign out and sign back in so the change takes effect - Put
sudoin front of everydockercommand in this guide
To add your account to the docker group, run this in a terminal on the Linux host:
sudo usermod -aG docker $USERGetting the Images
BridgeLink server images are on Docker Hub, in the innovarhealthcare/bridgelink repository. You can pull them without signing in to Docker Hub.
Choose an Image Variant
Each variant is a tag of the same repository:
| Image | What it is | Runs as |
|---|---|---|
innovarhealthcare/bridgelink:26.9.0 | The standard image, built on Rocky Linux 9 | User ID 1000 |
innovarhealthcare/bridgelink:26.9.0-dhi | The hardened image, built on a minimal Docker Hardened Image base with no package manager and no command-line tools. It is rebuilt every week to pick up operating system security fixes. | User ID 65532 |
innovarhealthcare/bridgelink:26.9.0-dhi-slim | The hardened image without the desktop Administrator client, for sites that manage BridgeLink only through WebAdmin | User ID 65532 |
Each tag also has a Java 17 form with -jdk17 added at the end, such as 26.9.0-jdk17, 26.9.0-dhi-jdk17 and 26.9.0-dhi-slim-jdk17. Unless you need Java 17, use the tags in the table.
The two hardened images run BridgeLink the same way as the standard one. They differ in the base system, the user ID (65532), having no shell, and writing MP_ values literally; the slim image also leaves out the Administrator client. The examples in this guide use the standard image. The Container Account lists the two changes for a hardened image.
Pull the Image
docker pull innovarhealthcare/bridgelink:26.9.0Setting Up the Deployment
Everything lives in one folder on the host: a Compose file and the appdata folder BridgeLink keeps its keystore and server ID in.
- Create the folder:
mkdir bridgelink- Go into it:
cd bridgelink- Create the
appdatafolder:
mkdir appdata- Give it to the container's user, ID
1000for the standard image:
sudo chown 1000:1000 appdata- Read the WebAdmin license terms: the Business Source License 1.1 and the BridgeLink WebAdmin Supplemental Terms. To read them without starting WebAdmin:
docker run --rm --entrypoint cat innovarhealthcare/bridgelink-webadmin:26.9.0 \
/app/LICENSE /app/SUPPLEMENTAL-TERMS.md- To accept them, create a file named
.envin thebridgelinkfolder with this one line. Compose reads it every time, so WebAdmin starts on every later command too:
echo BL_ACCEPT_LICENSE=1 > .env- In the
bridgelinkfolder, create a file nameddocker-compose.ymlwith the content below, for example withnano docker-compose.yml.
YAML depends on its indentation. If you are reading the PDF, do not copy the content from it: the copy loses the indentation and picks up page headers and footers. Copy it from the HTML version of this guide instead, or use the docker-compose.yml file that comes with this guide.
services:
bl:
image: innovarhealthcare/bridgelink:26.9.0
user: "1000:1000"
ports:
- "8443:8443"
volumes:
- ./appdata:/opt/bridgelink/appdata
environment:
MP_DATABASE: postgres
MP_DATABASE_URL: jdbc:postgresql://postgres:5432/bridgelinkdb
MP_DATABASE_USERNAME: bridgelink
MP_DATABASE_PASSWORD: change-me-database
MP_KEYSTORE_STOREPASS: change-me-store
MP_KEYSTORE_KEYPASS: change-me-key
security_opt:
- no-new-privileges:true
stop_grace_period: 35s
depends_on:
- postgres
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: bridgelinkdb
POSTGRES_USER: bridgelink
POSTGRES_PASSWORD: change-me-database
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
webadmin:
image: innovarhealthcare/bridgelink-webadmin:26.9.0
ports:
- "8444:8444"
environment:
PORT: "8444"
NODE_ENV: production
BRIDGELINK_SERVER_URL: https://bl:8443
BL_ACCEPT_LICENSE: ${BL_ACCEPT_LICENSE:-}
volumes:
- webadmin-certs:/app/certs
security_opt:
- no-new-privileges:true
depends_on:
bl:
condition: service_healthy
restart: unless-stopped
volumes:
pgdata:
webadmin-certs:- In
docker-compose.yml, replace eachchange-me-...value with a password of your own. Follow these rules:- Replace the whole value, including its
-database,-storeor-keyending - Use letters and digits only. Compose treats a
$as the start of a variable. With the standard image, a|inMP_DATABASE_PASSWORDcannot be written, so BridgeLink starts with an empty database password, cannot sign in to the database, and restarts again and again (see Troubleshooting). A backslash is unsafe in every password with both images, because BridgeLink readsmirth.propertieswith backslash as an escape character. - Use one password for the database and a different one for each keystore value
- Under
bl:, setMP_DATABASE_PASSWORD,MP_KEYSTORE_STOREPASSandMP_KEYSTORE_KEYPASS - Under
postgres:, setPOSTGRES_PASSWORDto the same value asMP_DATABASE_PASSWORD
- Replace the whole value, including its
What the settings do:
| Setting | Why it is there |
|---|---|
./appdata:/opt/bridgelink/appdata | Keeps the keystore and the server ID on the host, so they survive when the container is replaced |
MP_DATABASE and the other MP_DATABASE_... lines | Point BridgeLink at the postgres container. See Choosing and Connecting the Database. |
MP_KEYSTORE_STOREPASS and MP_KEYSTORE_KEYPASS | Fix the keystore passwords. The keystore lives in appdata and must open with the same passwords every time the container is created. |
no-new-privileges:true | Stops anything in the bl or webadmin container from gaining extra Linux privileges after it starts |
stop_grace_period: 35s | Lets BridgeLink shut down cleanly when the container stops. Messages still queued stay queued. |
BL_ACCEPT_LICENSE: ${BL_ACCEPT_LICENSE:-} | Takes your acceptance of the WebAdmin license terms from the .env file. The Compose file does not accept them for you. See Running WebAdmin. |
condition: service_healthy | Starts WebAdmin only once BridgeLink reports healthy, so the first sign-in does not reach BridgeLink before it has finished starting |
Run every docker compose command in this guide from the bridgelink folder. From any other folder, the commands fail with no configuration file provided: not found.
Choosing and Connecting the Database
Every BridgeLink server keeps its channels, messages, events, users and settings in one database. BridgeLink reads that choice from its settings file, conf/mirth.properties. In a container you set those settings with environment variables, and the container writes them into mirth.properties each time it starts.
Always Use an External Database in a Container
BridgeLink ships set to the default Derby database. Do not use it in a container:
- Cannot run on the
-jdk17tags. BridgeLink 26.9 will not start a server on the default Derby database with any Java older than 21. The standard images use Java 21, but the tags ending in-jdk17do not, and on those the server stops at once and logsembedded Derby requires Java 21+ as of 26.9; upgrade Java or switch to an external database. - Runs inside BridgeLink. Derby lives in the same process as the server, so no other tool can open the database while BridgeLink runs, and its files would have to live in a volume and be backed up by copying.
- Lacks features. The default Derby database does not support the JSON value type in Lookup Manager or regex search in Message Browser. SQL Server does not support regex search either.
- Sized for evaluation. For production message volumes, use PostgreSQL, MySQL, Microsoft SQL Server or Oracle.
The Compose file in Setting Up the Deployment runs PostgreSQL next to BridgeLink. To use a database server you already run, delete the postgres service and point the variables below at your server.
The Database Variables
| Variable | What to set |
|---|---|
MP_DATABASE | postgres, mysql, sqlserver or oracle |
MP_DATABASE_URL | The connection address, using the pattern below |
MP_DATABASE_USERNAME | The BridgeLink login |
MP_DATABASE_PASSWORD | That login's password |
| Database | MP_DATABASE_URL pattern |
|---|---|
| PostgreSQL | jdbc:postgresql://dbhost:5432/bridgelinkdb |
| MySQL | jdbc:mysql://dbhost:3306/bridgelinkdb |
| Microsoft SQL Server | jdbc:sqlserver://dbhost:1433;databaseName=bridgelinkdb |
| Oracle | jdbc:oracle:thin:@//dbhost:1521/servicename for a service name (pluggable databases), or jdbc:oracle:thin:@dbhost:1521:SID for a SID |
For an existing database server, first create an empty database for BridgeLink and a login that owns it and can create tables. BridgeLink creates all of its tables the first time it starts.
Setting Any Other Property
Any variable that starts with MP_ sets the matching line in mirth.properties. Drop the MP_ prefix, turn each __ into -, turn each remaining _ into ., and change every letter to lowercase. For example, MP_DATABASE__READONLY_MAX__CONNECTIONS sets database-readonly.max-connections.
Because the name is lowercased, you cannot set a property whose name has a capital letter this way. The one exception is MP_SERVER_ALLOWROOT.
Two other variables do not follow this rule. MP_VMOPTIONS writes the vmoptions file rather than a line in mirth.properties, as Memory for the BridgeLink Server describes, and MP_DATABASE_RETRY_WAIT sets database.connection.retrywaitinmilliseconds, the wait in milliseconds between database connection attempts at startup.
The Container Account
In a container, BridgeLink runs as the user the container runs as. That user decides what BridgeLink can write to, the job a service account does on a server.
Why Not Root
Channels can run scripts. If BridgeLink runs as root, any script in any channel has full control of the container. So BridgeLink refuses to start as root by default, and the log shows:
ERROR: BridgeLink is running as root/Administrator.
The BridgeLink images already run as a non-root user:
| Image | User ID |
|---|---|
Standard (tag 26.9.0) | 1000 |
Hardened (tags 26.9.0-dhi and 26.9.0-dhi-slim) | 65532 |
Keep the user: line in the Compose file matched to your image, and never set it to root or 0.
Any host folder you mount into the BridgeLink container, such as appdata, must belong to that user ID so BridgeLink can write to it.
Using a Hardened Image
Make these two changes to Setting Up the Deployment:
- Give
appdatato user ID65532instead of1000:
sudo chown -R 65532:65532 appdata- In
docker-compose.yml, change theimage:anduser:lines underbl:so they read:
services:
bl:
image: innovarhealthcare/bridgelink:26.9.0-dhi
user: "65532:65532"A hardened container has no shell and no command-line tools, so docker compose exec bl sh fails with executable file not found. To check a hardened container, read its log with docker compose logs bl and look at the files in appdata on the host.
Changing the User After Setup
Suppose the deployment ran with one image and you switch to the other, or you change the user: line. The files in appdata still belong to the old user ID. The new user cannot write the keystore or its other files, and BridgeLink fails with Permission denied errors.
- Stop BridgeLink:
docker compose stop bl- Give
appdatato the new user ID, for example65532:
sudo chown -R 65532:65532 appdata- In
docker-compose.yml, change theimage:anduser:lines underbl:to the new image and user ID. For the hardened image, they read:
services:
bl:
image: innovarhealthcare/bridgelink:26.9.0-dhi
user: "65532:65532"- Give the new user ID the same access to any other host folders you mount for your channels.
- Start BridgeLink with the new settings:
docker compose up -d blStarting BridgeLink for the First Time
- From the
bridgelinkfolder, start everything:
docker compose up -ddocker compose up -d does not return until bl reports healthy, because WebAdmin waits for it. On a normal start that takes about a minute or less. If the command has not returned after a couple of minutes, open a second terminal in the bridgelink folder, run step 2 to see what bl is doing, and see Troubleshooting.
- Follow the BridgeLink log:
docker compose logs -f bl- Wait for the newest line that contains
Web server running at, with a time after the start you just made. That line is the sign that BridgeLink started. Each log line begins with the container name, the log level and a time, so look for the text anywhere in the line. - Find the newest line that contains
Running, to check the database name and Java version. Confirm it showspostgres, notderby. - Press
Control-Cto stop following the log. The containers keep running. - Check the containers:
docker compose psThe bl container reports healthy once BridgeLink has started and finished deploying its channels. A first start can take longer on a slow host or a host that is busy with other work.
A Running line on its own does not mean BridgeLink started. If the keystore cannot be opened, or appdata cannot be written, the log still shows Running, but it never shows Web server running at, and port 8443 refuses connections. See Troubleshooting.
On this first start, BridgeLink:
- Creates its tables in the database
- Creates a keystore in
appdataholding a new self-signed certificate for port8443 - Creates
appdata/server.id, which holds this server's unique ID
If PostgreSQL is still starting when BridgeLink first tries it, BridgeLink retries twice, 10 seconds apart, then stops. restart: unless-stopped starts it again, so give it a minute before you look for a problem.
Memory for the BridgeLink Server
BridgeLink starts with a 256 MB Java heap, which is enough for a personal or test install but small for production. The release's blserver.vmoptions sets it.
To change it, add MP_VMOPTIONS at the end of the environment: section under bl: in docker-compose.yml. A bare number sets the heap in MB:
services:
bl:
environment:
MP_KEYSTORE_KEYPASS: your-keystore-key-password
MP_VMOPTIONS: "1024"Leave memory for the host and for the database. If you give the container a memory limit, the limit must be larger than the heap. To apply the change, run this from the bridgelink folder:
docker compose up -d blRunning WebAdmin
WebAdmin is the browser-based tool you use to manage BridgeLink. In Docker it is always a separate container: no BridgeLink image includes it. The Compose file in Setting Up the Deployment already runs it.
The WebAdmin Container
| Setting | What it does |
|---|---|
image: innovarhealthcare/bridgelink-webadmin:26.9.0 | The WebAdmin image. It also includes the screens for commercial plugins such as SSL Settings, OIDC and Access Control, so you need no other image. |
BRIDGELINK_SERVER_URL: https://bl:8443 | Locks WebAdmin to the bl container. The address must start with https://. |
BL_ACCEPT_LICENSE: ${BL_ACCEPT_LICENSE:-} | Passes on your acceptance of the Business Source License 1.1 (the license WebAdmin is released under) and the BridgeLink WebAdmin Supplemental Terms, from the BL_ACCEPT_LICENSE=1 line in .env. Read both before you accept. Without the .env line, the container prints a short notice that points to the terms, not the terms themselves, and stops. Because of restart: unless-stopped it keeps restarting, at first every few seconds and then about once a minute, printing the notice each time. |
webadmin-certs:/app/certs | Keeps WebAdmin's certificate when the container is replaced |
WebAdmin reaches BridgeLink over the Docker network by the service name bl.
Sign In for the First Time
- Open
https://your-docker-host:8444in a browser. - If the browser shows a certificate warning, click Advanced, then Proceed to ... (unsafe) in Chrome or Continue to ... (unsafe) in Edge. In Firefox, click Advanced, then Accept the Risk and Continue. Read the note after this step.
- In Username, type
admin. - In Password, type
admin. - Click Login.
- On Welcome to BridgeLink, leave Username as
admin. - In New Password, type a new password of at least 8 characters, with an uppercase letter, a lowercase letter, a number, and a special character such as
!,@,#,$,%or*. A hyphen, period or space does not count as a special character, and the password cannot beadmin. WebAdmin lists only the rules thatadminbreaks, so check your password against all of these. - Type it again in Confirm Password.
- The profile fields on Welcome to BridgeLink are optional; fill them in if you want to.
- Click Save & Continue.

Controlling the WebAdmin Container
WebAdmin runs in its own container, so you control it with Docker Compose from the bridgelink folder. WebAdmin's errors go to its container log:
docker compose logs webadminTo restart WebAdmin:
docker compose restart webadminMore WebAdmin Setups
For WebAdmin outside Docker, one WebAdmin for several servers, your own certificate, and every setting, see the BridgeLink WebAdmin Setup Guide on the BridgeLink download page, https://www.bridgelink.net/download.
Finding the Server ID
Every BridgeLink server has a unique server ID, created the first time it starts. Plugin licenses are issued against this ID, so Innovar Healthcare asks for it when you license a plugin.
In WebAdmin
- Sign in to WebAdmin.
- In the left sidebar, scroll to the bottom and, under Help, click About BridgeLink.
If Update Available opens instead, click Got it, then click About BridgeLink again.
- Click the copy icon beside Server ID.

On the Host
The same ID is in the appdata folder you mounted:
sudo cat appdata/server.idThe file holds one line in the form server.id = <ID>. The ID is the part after the equals sign.
Back up the whole appdata folder together with your docker-compose.yml (and .env, if you use one). Besides server.id and keystore.jks, appdata holds the Configuration Map. The keystore holds the key BridgeLink uses to encrypt data, and the Compose file holds the keystore passwords. The database is separate: channels, users, settings and messages live in the pgdata volume, so back up the database too, for example with pg_dump. If you use the mirth_properties secret, back up that file as well. Settings changed at runtime in mirth.properties are lost when the container is recreated; set them with MP_ variables instead.
Keep the ID Fixed
A container is easy to replace, and a replaced container without its appdata folder would get a new ID. To make sure the ID never changes, set it in the Compose file once you have it:
- Copy the ID from About BridgeLink.
- In
docker-compose.yml, find thebl:service and theenvironment:section inside it, the one with theMP_lines. Add this line at the end of that section, lined up with theMP_lines, with your ID in place ofyour-server-id. Keep the indentation exactly as shown, because YAML depends on it:
services:
bl:
environment:
MP_KEYSTORE_KEYPASS: your-keystore-key-password
SERVER_ID: your-server-id- Apply the change, from the
bridgelinkfolder:
docker compose up -d blThe container writes this ID into appdata/server.id every time it starts.
Replacing the Certificates
A new deployment uses two self-signed certificates (certificates the server creates for itself, which browsers do not trust), which is why browsers warn the first time. Before you use BridgeLink in production, replace them with certificates from your organization's certificate authority (CA).
| Certificate | Port | Who sees it | Where it lives |
|---|---|---|---|
| WebAdmin | 8444 | Every browser that opens WebAdmin | /app/certs/server.crt and server.key in the webadmin container |
| BridgeLink server | 8443 | WebAdmin and any program that calls the BridgeLink API | The mirthconnect entry in appdata/keystore.jks |
This chapter has two separate procedures, one for each certificate. Each has its own numbered steps, and you do not need to do one to do the other.
Replace the WebAdmin Certificate
Before you replace WebAdmin's certificate, read When a browser stops letting you click through under Sign In for the First Time in Running WebAdmin.
You need the certificate and its private key as PEM files (text files that begin with -----BEGIN). The certificate must be one that users' browsers trust, and it must name the address they type to reach WebAdmin. Put any intermediate certificates in the certificate file after the server certificate. The private key file must not have a password.
- Create a folder on the host for them:
sudo mkdir -p /etc/ssl/bridgelink-webadmin- Copy your certificate into it as
server.crt. Replace/path/to/your-certificate.pemwith the path to your own certificate file:
sudo cp /path/to/your-certificate.pem /etc/ssl/bridgelink-webadmin/server.crt- Copy your private key into it as
server.key. Replace/path/to/your-private-key.pemwith the path to your own key file:
sudo cp /path/to/your-private-key.pem /etc/ssl/bridgelink-webadmin/server.key- Give the folder to the WebAdmin container's user, ID
1000:
sudo chown -R 1000:1000 /etc/ssl/bridgelink-webadmin- Make the private key readable only by its owner:
sudo chmod 600 /etc/ssl/bridgelink-webadmin/server.key- In
docker-compose.yml, find thewebadmin:service. Replace its existing- webadmin-certs:/app/certsline with the line below, and leave the othervolumes:sections as they are. Include the-at the start of the line, because it is part of the file. Keep the indentation exactly as shown, because YAML depends on it:
webadmin:
volumes:
- /etc/ssl/bridgelink-webadmin:/app/certs:ro- Recreate the WebAdmin container, from the
bridgelinkfolder:
docker compose up -d webadmin- Open WebAdmin in a browser and confirm there is no certificate warning.
To Undo the Swap
If browsers cannot open WebAdmin after the swap, put the old certificate back:
- In
docker-compose.yml, put the- webadmin-certs:/app/certsline back in place of the line you added in step 6. - Recreate the WebAdmin container, from the
bridgelinkfolder:
docker compose up -d webadminThe original certificate returns from the webadmin-certs volume.
Browsers that opened WebAdmin by its server name with the new certificate refuse the old self-signed one. Fix the new certificate instead, or clear the browser's HSTS entry for the server name: open chrome://net-internals/#hsts in Chrome or edge://net-internals/#hsts in Edge, and use Delete domain security policies. In other browsers, clear the browsing data for that server name.
Replace the BridgeLink Server Certificate
BridgeLink keeps its certificate in a keystore file under the name mirthconnect. The same keystore also holds the key BridgeLink uses to encrypt data, so replace only the mirthconnect entry. Never swap in a different keystore file.
You need the certificate and private key as a PKCS12 file (a single file, ending in .p12 or .pfx, that bundles a certificate with its private key) and its password, plus keytool on the host, which comes with any Java 17 or 21 install.
The commands below contain placeholders in angle brackets. Replace each one, including the angle brackets, with your own value:
| Placeholder | Where the value comes from |
|---|---|
<your MP_KEYSTORE_STOREPASS value> | The MP_KEYSTORE_STOREPASS value under bl: in your docker-compose.yml |
<your MP_KEYSTORE_KEYPASS value> | The MP_KEYSTORE_KEYPASS value under bl: in your docker-compose.yml |
<your .p12 file password> | The password set on your PKCS12 file when it was created, which you get from whoever issued or exported the file |
<the entry name from step 4> | The name that keytool lists for the entry in your PKCS12 file in step 4 |
- Stop BridgeLink:
docker compose stop bl- Back up the keystore:
sudo cp appdata/keystore.jks keystore.jks.bak- Copy your PKCS12 file into the
bridgelinkfolder asserver.p12. The commands that follow run from that folder and expect the file there. - List the entry name inside your PKCS12 file:
keytool -list -keystore server.p12 -storetype PKCS12- Remove the old certificate entry:
sudo keytool -delete -alias mirthconnect -keystore appdata/keystore.jks \
-storetype JCEKS -storepass <your MP_KEYSTORE_STOREPASS value>- Import yours as
mirthconnect:
sudo keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 \
-srcstorepass <your .p12 file password> \
-srcalias <the entry name from step 4> \
-destkeystore appdata/keystore.jks -deststoretype JCEKS \
-deststorepass <your MP_KEYSTORE_STOREPASS value> -destalias mirthconnect \
-destkeypass <your MP_KEYSTORE_KEYPASS value>Steps 5 and 6 print a warning that recommends migrating the keystore to PKCS12. Ignore it: BridgeLink reads the keystore as JCEKS, so do not convert it.
- Give the keystore back to the container's user, ID
1000for the standard image:
sudo chown 1000:1000 appdata/keystore.jksFor a hardened image, which runs as user 65532, run this instead:
sudo chown 65532:65532 appdata/keystore.jks- Start BridgeLink:
docker compose start bl- Open
https://your-docker-host:8443in a browser and confirm the browser shows your certificate.
If BridgeLink does not start, or port 8443 does not answer: stop BridgeLink, copy the backup keystore.jks.bak you made in step 2 back to appdata/keystore.jks, repeat the chown from step 7, and start BridgeLink.
WebAdmin keeps working through the change, with no change to its own settings.
The Data Pruner
BridgeLink keeps the messages each channel processes until the Data Pruner removes them. The Data Pruner is off on a new server, so turn it on before you send real traffic through BridgeLink; otherwise the database grows with every message.
It has two parts, and both have to be set:
- The schedule, for the whole server: in WebAdmin, in the left sidebar under Administration, click Settings, then the Data Pruner tab
- How long each channel keeps messages: on each channel's Summary tab, under Message Pruning. A channel whose pruning fields are blank is never pruned, even when the schedule is on.
Choose ages that match your organization's record-keeping rules.
Turn On the Schedule
- In WebAdmin, in the left sidebar under Administration, click Settings.
- Click the Data Pruner tab.
- Under Schedule, set Enable to Yes.
- Choose a Schedule Type and set when it runs: Interval runs every set number of hours or minutes, Time runs once a day, and Cron takes cron expressions. Once a day at a quiet hour suits most servers.
- Click Save.

Set How Long Each Channel Keeps Messages
- In the left sidebar under Build, click Channels.
- Double-click the channel to open it in the channel editor.
- On the Summary tab, under Message Pruning, enter the number of days in Prune metadata after and Prune content after. Content cannot be kept longer than metadata.
- Click Save.
- Repeat for each channel.

Incomplete and queued messages are never pruned. Errored messages are kept too, unless you check Prune errored messages.
Troubleshooting
| Symptom | Likely cause | What to do | |
|---|---|---|---|
The bl container on a -jdk17 tag exits at once, and docker compose logs bl shows "embedded Derby requires Java 21+ as of 26.9; upgrade Java or switch to an external database" | MP_DATABASE is missing, so BridgeLink fell back to the default Derby database, which the -jdk17 tags cannot run | Set the four MP_DATABASE variables. See The Database Variables. The standard images do not exit in this case: they start quietly on Derby, so check that the Running log line shows postgres. | |
The bl container exits at once, and the log shows "ERROR: BridgeLink is running as root/Administrator." | The user: line was set to root or 0 | Set user: to "1000:1000" for the standard image or "65532:65532" for a hardened one. | |
The command docker compose up -d does not finish. docker compose ps -a shows bl as health: starting and webadmin as Created, and docker compose logs bl shows "Permission denied" for files in appdata, such as appdata/keystore.jks. | appdata does not belong to the container's user ID. bl does not exit: it keeps running without being able to start, and WebAdmin waits for it. | On a Linux host, run sudo chown -R 1000:1000 appdata (65532:65532 for a hardened image), then run docker compose restart bl and docker compose up -d. On Docker Desktop the fix is the opposite: chown is what locks BridgeLink out of appdata, so do not run it, unless your project folder is inside a WSL2 Linux filesystem, where files keep their real ownership. | |
The command docker compose up -d ends with "dependency failed to start: container bridgelink-bl-1 is unhealthy", but only after about six minutes | bl never became healthy, so WebAdmin was not started. Docker marks bl unhealthy only after it has had about six minutes to start. | Run docker compose logs bl and read the last lines. A "Permission denied" error on appdata is a common cause, described in the row above. A database login failure is another, described in the row below. | |
The bl container exits and restarts again and again, and docker compose up -d never finishes | BridgeLink cannot connect to or log in to the database. Each restart resets the health start period, so docker compose up -d keeps waiting. A common cause is changing POSTGRES_PASSWORD after the pgdata volume was first created. With the standard image, a ` | in MP_DATABASE_PASSWORD` leaves the database password empty, with the same result. SQL Server only: its certificate is self-signed, comes from an internal certificate authority, or does not match the host name in the URL, which BridgeLink 26.9 does not accept by default. | Run docker compose logs bl and read the database error. Set POSTGRES_PASSWORD and MP_DATABASE_PASSWORD back to the values used when pgdata was first created. See SQL Server and certificates under The Database Variables in Choosing and Connecting the Database. |
The first docker command fails with "permission denied while trying to connect to the docker API at unix:///var/run/docker.sock" | Your account is not allowed to use Docker | Add your account to the docker group with sudo usermod -aG docker $USER, then sign out and back in, or put sudo in front of every docker command. See Run Docker Without Root. | |
The bl container starts, but port 8443 does not answer after the container was recreated. The log shows "Running" but never "Web server running at", and it mentions the keystore. | The keystore passwords changed, so BridgeLink cannot open the keystore in appdata | Set MP_KEYSTORE_STOREPASS and MP_KEYSTORE_KEYPASS back to the values used when appdata/keystore.jks was created. | |
The webadmin container exits at once or keeps restarting | The license terms were not accepted: .env is missing, is not in the folder with docker-compose.yml, or its line is not exactly BL_ACCEPT_LICENSE=1 | Fix .env and run docker compose up -d webadmin. | |
| WebAdmin sign-in shows "Could not reach the BridgeLink server. Verify the server address is correct and the server is running." | bl is not running or not healthy yet, or BRIDGELINK_SERVER_URL is wrong | Check docker compose ps -a, and confirm the URL is https://bl:8443. | |
| The browser warns about the certificate | WebAdmin still uses its self-signed certificate | Click through the warning, or replace the certificate. See Replace the WebAdmin Certificate. If the browser offers no way to continue, it is enforcing HSTS for that name. See When a browser stops letting you click through under Sign In for the First Time, and To Undo the Swap in Replacing the Certificates to clear it. |
For more WebAdmin problems, see Troubleshooting in the BridgeLink WebAdmin Setup Guide.
Support
Customers with an active Innovar Healthcare support plan can contact support at support@innovarhealthcare.com. Include the BridgeLink image and tag (or digest), your Compose file with the passwords removed, what you were doing, and the most recent part of docker compose logs bl. docker compose logs bl can contain message content, which may include patient data. Remove patient data before you send a log, or ask support for a secure way to send it.