Skip to main content

Deploy OpenLM Router

To put the Router in your network, deploy it as a Docker Compose stack on a Linux host. When the stack is running, connect it to OpenLM Platform and define your failover pairs in Configure OpenLM Router.

Before you begin​

Confirm these prerequisites:

  • A Linux host that meets the system requirements, with Docker Engine and the Docker Compose v2 plugin installed.
  • Network access from the host to your OpenLM Platform and to each license server's lmgrd port.
  • License servers that OpenLM Platform monitors through the OpenLM Broker, as described in System requirements.
  • The encryption key you generated in System requirements.

Get the images​

The Router images are published to the OpenLM public registry and pull anonymously, so you need no docker login and no pull secret. To pull the images, run these commands:

docker pull public.ecr.aws/r3q3q2f4/olm-routerapi:1.261006.0752
docker pull public.ecr.aws/r3q3q2f4/olm-routerui:1.261008.0932

Tags are build numbers in the form 1.<yymmdd>.<hhmm>. The registry has no latest or other moving tag, so pin an explicit tag on each image and record which builds you deployed. OpenLM releases the two images separately, so their tags can differ.

Find the available builds​

The tags on this page are the builds that this guide covers. To see every build that the registry holds for an image, list the image's tags. The registry issues the access token anonymously, so you need no account.

On Linux, with curl and jq:

repo=olm-routerapi # or olm-routerui
token=$(curl -s "https://public.ecr.aws/token/?service=public.ecr.aws&scope=repository:r3q3q2f4/$repo:pull" | jq -r .token)
curl -s -H "Authorization: Bearer $token" "https://public.ecr.aws/v2/r3q3q2f4/$repo/tags/list" | jq -r '(.tags // [.errors[0].message])[]' | sort

In PowerShell:

$repo = "olm-routerapi" # or olm-routerui
$token = (Invoke-RestMethod "https://public.ecr.aws/token/?service=public.ecr.aws&scope=repository:r3q3q2f4/${repo}:pull").token
(Invoke-RestMethod "https://public.ecr.aws/v2/r3q3q2f4/$repo/tags/list" -Headers @{ Authorization = "Bearer $token" }).tags | Sort-Object

Run the commands once for each image. The tags sort in build order, so the last line is the most recent build. If the output is Rate exceeded, or PowerShell reports TOOMANYREQUESTS, the registry is limiting anonymous requests: wait 5 seconds and run the commands again.

Create the environment file​

In a working directory on the host, for example ~/openlm-router/, create a file named .env:

# The MongoDB account the Compose file creates on the first start.
MONGO_USER=router
MONGO_PASSWORD=<your-generated-password>

# The key protecting the stored Platform client secret. Paste the string that
# `openssl rand -base64 32` printed, exactly as it printed it.
ADMISSION_PLATFORM_ENCRYPTION_KEY=<your-generated-key>

Generate the MongoDB password with openssl rand -hex 16. The password becomes part of a connection string, so a password with characters such as @, :, or / breaks the connection from the Router to MongoDB. MongoDB creates the account only when its data volume is empty, so changing the password later does not change the existing account.

Never reuse an encryption key from a sample or a development stack. Generate your own, as described in System requirements.

Create the proxy file for the Router UI​

The Router UI is served under the /router-management/ path and expects a reverse proxy in front of it that strips that prefix and forwards API calls to the Router. Create router-ui-proxy.conf beside the .env file:

server {
listen 8101;

# The Router UI, with the /router-management prefix stripped.
location /router-management/ {
proxy_pass http://127.0.0.1:8102/;
}

# API calls from the browser, forwarded to the Router.
location /api/routerapi/ {
proxy_pass http://127.0.0.1:8100/api/;
}
}

Create the Compose file​

Create docker-compose.yml in the same directory:

services:
mongo:
image: mongo:7
ports:
- "127.0.0.1:27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USER}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
volumes:
- mongo_data:/data/db
restart: unless-stopped

redis:
image: redis:7
command:
- redis-server
- --appendonly
- "yes"
- --appendfsync
- everysec
- --maxmemory-policy
- noeviction
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped

routerapi:
image: public.ecr.aws/r3q3q2f4/olm-routerapi:1.261006.0752
depends_on: [mongo, redis]
# Host networking so each pair's listen port lands on a real host address that
# workstations can reach, and so the license server sees the Router host as the
# source. Listen ports are opened at runtime, after a pair is configured, so they
# cannot be declared under `ports:` ahead of time.
network_mode: host
environment:
- MONGODB__CONNECTIONSTRING=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@localhost:27017/?authSource=admin
- REDIS__CONNECTIONSTRING=localhost:6379,abortConnect=false
- ADMISSION_PLATFORM_ENCRYPTION_KEY=${ADMISSION_PLATFORM_ENCRYPTION_KEY}
# Required. The Router takes its configuration from the OpenLM Platform.
- licOpsConfiguration__enabled=true
- LICOPSCONFIGURATION_ENABLED=true
# Required. Declares a failover Router. Fixed at the first start.
- ROUTER_CONFIG_BOOTSTRAP_MODE=basic
- ROUTER_CORRELATION_MODE=Ip
- ROUTER_PROXY_PROTOCOL_ENABLED=false
- ROUTER_TRUSTED_CIDR=127.0.0.1/32
# Keep the background-job dashboard off.
- hangfire__dashboard__enabled=false
restart: unless-stopped

routerui:
image: public.ecr.aws/r3q3q2f4/olm-routerui:1.261008.0932
ports:
- "127.0.0.1:8102:8101"
environment:
- LB_FQDN=_
restart: unless-stopped

routerui-proxy:
image: nginx:stable
depends_on: [routerui]
network_mode: host
volumes:
- ./router-ui-proxy.conf:/etc/nginx/conf.d/default.conf:ro
restart: unless-stopped

volumes:
mongo_data:
redis_data:

Keep the Router settings exactly as shown:

  • licOpsConfiguration__enabled and LICOPSCONFIGURATION_ENABLED make the Router take its configuration from OpenLM Platform. Without them you cannot configure the Router for failover.
  • ROUTER_CONFIG_BOOTSTRAP_MODE=basic declares that this Router serves failover pairs. When the Router connects, OpenLM Platform creates an empty starting configuration for it. Without this setting OpenLM Platform creates nothing, and the Router stays idle until a configuration exists.

The mode is fixed when the Router first starts. To change it, deploy a new Router with its own empty MongoDB database, and stop the old one.

Use the exact variable names shown

MONGODB__CONNECTIONSTRING and REDIS__CONNECTIONSTRING take two underscores before CONNECTIONSTRING. The Router substitutes these names into its configuration at startup, so a misspelling is not merely ignored. The value lands empty and the container exits at boot with Mongo ConnectionString cannot be null or empty.

The connection strings use localhost because the Router uses host networking. MongoDB and Redis publish their ports on 127.0.0.1 only, so the Router reaches them on the host while nothing outside the host can. If you run MongoDB and Redis on servers you already operate, change the two connection strings to point at them. The Router UI publishes its port on 127.0.0.1 too, on port 8102, and the proxy serves it to browsers on port 8101.

Start the stack​

To start the stack and follow the Router API log, run these commands:

docker compose up -d
docker compose logs -f routerapi

On the first start, the Router creates its identity and logs that it takes its configuration from OpenLM Platform:

Bootstrap seed skipped: the Router is service-managed (LicOps configuration enabled); identity RouterId <guid> established.
Router configuration shape: service-managed; ...

Confirm the Router is answering:

curl http://localhost:8100/api/v1/status
{
"status": "unconfigured",
"configurationManagement": {
"shape": "serviceManaged",
"routerId": "a76db42e-5d48-497d-bbbb-f66dc04d9d5f",
"lastSync": {
"lastSuccessfulSync": null,
"lastFailure": "No Platform connection is configured, so the Router has no address for the LicOps Configuration service"
}
}
}

This is the correct result for a new Router. It is running but has not been connected to OpenLM Platform, so it has no configuration and no client port is open. Check the status field. The Router receives its configuration from OpenLM Platform after you connect it.

The routerId is created once and stored in MongoDB. It is how OpenLM Platform tells this Router apart from others. Wiping the database creates a new one, which OpenLM Platform sees as a different Router.

The interactive API reference is at http://<router-host>:8100/swagger.

Verify the deployment​

Confirm the containers are running and the Router UI loads:

docker compose ps
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8101/router-management/

The second command prints 200. Open http://<router-host>:8101/router-management/ in a browser. A red notice that no Platform connection is configured is expected until you complete the next step.

The readiness endpoints of the Router, /readyz and /health/ready, answer 503 until the Router has collected its configuration from OpenLM Platform. On a new installation this is expected, not a fault.

Next step

Continue to Configure OpenLM Router to connect the Router to OpenLM Platform and define your first failover pair. To upgrade this deployment later, see Change, upgrade, or remove OpenLM Router.

The documentation team might draft this page using a large language model. A technical writer reviews every page and verifies it against the product before publishing it. A human makes the final decision.