FleetbaseFleetbase

Socket

Configure and monitor the SocketCluster server that powers real-time driver tracking, order status updates, and live console events, including authenticated channel subscriptions.

Socket

Fleetbase uses SocketCluster for real-time bidirectional communication — live driver location updates on the map, order status changes pushed to the console without polling, and real-time events delivered to the Navigator app. Navigate to Admin → System Settings → Socket to monitor the connection.

For WebSocket ingress requirements, SocketCluster replica guidance, and network planning, see Infrastructure Sizing.

Connection Monitor

The Socket page displays a live event log from the SocketCluster server. Events appear as they are received, with timestamps and color-coded output. This view is read-only — SocketCluster configuration is managed at the infrastructure level and cannot be changed from this page.

Socket Connection Monitor — live event log with timestamps and color-coded output

Configuration

SocketCluster runs in its own container, built from the fleetbase/fleetbase-socket image. It has two listeners:

PortPurposeExpose publicly?
8000WebSocket at /socketcluster/ and GET /health-check. Docker Compose maps it to host port 38000.Yes, through your WebSocket-aware ingress
8001Internal signed POST /publish and GET /stats, used only by the APINever. Keep it on the private container network

Do not publish port 8001 in docker-compose.override.yml, a Kubernetes Service, or an ingress rule. The API reaches it over the internal network (http://socket:8001 in Docker Compose).

SocketCluster is configured via environment variables set in docker-compose.override.yml under the socket service:

services:
  socket:
    environment:
      SOCKETCLUSTER_OPTIONS: '{"origins":"https://console.yourdomain.com"}'

The origins value is a comma-separated list of allowed WebSocket origins. In production, restrict this to your exact console domain to prevent connections from unauthorized origins.

The API container connects to SocketCluster using these variables (set under the application service):

VariableDefaultDescription
SOCKETCLUSTER_HOSTsocketHostname of the SocketCluster container
SOCKETCLUSTER_PORT38000Port SocketCluster listens on
SOCKETCLUSTER_SECUREfalseSet to true when connecting over WSS
SOCKETCLUSTER_PATH/socketcluster/WebSocket path prefix

Socket Authentication

Channel subscriptions are authenticated with short-lived tokens (JWTs) that the API mints: the console, the Navigator and Storefront apps, and API integrations (POST /v1/socket/token) all fetch one before connecting. The socket server verifies each token and checks every subscription against it, asking the API when it cannot decide locally. Only the API can publish events; it does so through the internal listener on port 8001, signing each request.

Socket authentication is off by default. It is switched on with SOCKETCLUSTER_AUTH_ENABLED=true, set to the same value on the API containers and the socket server, together with a valid SOCKETCLUSTER_AUTH_KEY. Until then a provisioned key changes nothing, so existing clients that connect without tokens keep working.

What the switch gates

SOCKETCLUSTER_AUTH_ENABLED off (default)On, with a valid key
Token routes (POST /v1/socket/token and the console, Navigator and Storefront equivalents)Answer 404; clients connect without a tokenMint short-lived socket tokens
API authorize endpoint (/int/v1/socket/authorize)InactiveAnswers the socket server's subscription checks
How the API publishes eventsLegacy websocket path, as a plain socket clientSigned POST /publish to the internal listener
Socket serverMode forced to off whatever SOCKETCLUSTER_AUTH_MODE says; the internal publish and stats endpoints answer 503Runs in SOCKETCLUSTER_AUTH_MODE

SOCKETCLUSTER_AUTH_MODE=enforce requires SOCKETCLUSTER_AUTH_ENABLED=true on the application, queue and scheduler containers. With the switch off there, the API keeps publishing over the legacy websocket path, which an enforcing socket server refuses, so real-time events stop. Always set the switch to the same value on the API and the socket server.

Environment variables

VariableSet onDefaultDescription
SOCKETCLUSTER_AUTH_ENABLEDapplication, queue, scheduler and socketfalseSwitches socket authentication on (true; the socket server also accepts 1, yes, on). Must be the same on every API container and the socket server. While it is off, or the key is missing or invalid, the token routes return 404, the API publishes over the legacy websocket path, and the socket server runs in off mode with a warning.
SOCKETCLUSTER_AUTH_KEYapplication, queue, scheduler and socketunsetShared secret, at least 32 characters. Must be identical on every API container and the socket server. Can be provisioned before the switch is turned on; unset keeps socket authentication off.
SOCKETCLUSTER_AUTH_MODEsocketenforce once switched on with a key, otherwise offoff, log or enforce (see below). Ignored while SOCKETCLUSTER_AUTH_ENABLED is off. enforce requires the switch on the API too.
SOCKETCLUSTER_PUBLISH_URLapplication, queue, schedulerhttp://{SOCKETCLUSTER_HOST}:8001Base URL of the socket server's internal listener. The API posts events to {url}/publish.
SOCKETCLUSTER_ORIGINapplication, queue, schedulerunsetOrigin header the API sends when it publishes over the websocket, which it does while socket authentication is off. Required when SOCKETCLUSTER_OPTIONS restricts origins, and must be one of the allowed origins, e.g. https://console.yourdomain.com. scripts/docker-install.sh and flb install-fleetbase write the console origin to .env and keep an existing value.
SOCKETCLUSTER_AUTHORIZE_URLsockethttp://application:8000/int/v1/socket/authorizeThe API's internal authorize endpoint, reached over the private network
SOCKETCLUSTER_TOKEN_TTLapplication900Lifetime of user, driver, customer and API-key socket tokens, in seconds
SOCKETCLUSTER_INTERNAL_PORTsocket8001Port of the internal listener

Generate a key with, for example:

openssl rand -hex 32

With Docker Compose, put the settings in the project .env file next to docker-compose.yml; the bundled compose file passes them to the application, queue, scheduler and socket services, so the switch and the key stay identical everywhere:

# .env
SOCKETCLUSTER_AUTH_ENABLED=true
SOCKETCLUSTER_AUTH_KEY=<64 hex characters>
SOCKETCLUSTER_AUTH_MODE=log

Fresh installs made with scripts/docker-install.sh or flb install-fleetbase generate a key but write SOCKETCLUSTER_AUTH_ENABLED=false and SOCKETCLUSTER_AUTH_MODE=log, so socket authentication stays off until you turn it on (see Turning on socket authentication). Re-running either installer keeps the values already in .env. Keep the key stable: changing it invalidates every token already handed out (clients simply fetch a new one). Restart the containers after editing .env.

Modes

ModeSubscriptionsClient publish / transmit / invoke
offAll allowed; the API is never asked. Tokens are still verified when presented.Allowed
logChecked and allowed. Each subscription that would be denied is logged as one JSON line with "event":"socket_auth_deny" (the token itself is never logged).Allowed, logged
enforceOnly authorized subscriptions succeed. Anonymous subscriptions are rejected, and sockets are removed from their channels when their token expires or is revoked.Refused

What a token may subscribe to:

  • Console users and API keys — their own company channel (company.{company uuid}), their own user.{id} or api.{key id} channel, and channels of records that belong to the same company.
  • Drivers — their own driver channel, their current vehicle, the orders assigned to them, and chats they take part in.
  • Storefront customers — their own orders and the drivers and vehicles serving those orders.

Turning on socket authentication

This applies to fresh installs and to upgraded instances alike. Turn it on in this order:

  1. Ship clients that fall back on 404. Deploy the new socket server and set the same SOCKETCLUSTER_AUTH_KEY on the application, queue, scheduler and socket services, leaving SOCKETCLUSTER_AUTH_ENABLED=false. Upgrade the console, Navigator and Storefront apps, and move custom integrations to tokens (see Migrating to Authenticated Socket Channels). These clients request a token and connect without one while the token route answers 404, so nothing breaks yet.
  2. Switch on in log mode. Set SOCKETCLUSTER_AUTH_ENABLED=true on the application, queue, scheduler and socket services, with SOCKETCLUSTER_AUTH_MODE=log, and restart them. Clients now receive tokens and the API publishes through the signed internal endpoint, but every subscription is still allowed. Watch the socket server logs for socket_auth_deny lines; the client field tells you which app or version made the request.
  3. Enforce. When the remaining denials are only traffic you expect to lose, set SOCKETCLUSTER_AUTH_MODE=enforce and restart the socket service.

Do not jump to enforce without step 2: an enforcing socket server refuses the legacy publish path that the API uses while SOCKETCLUSTER_AUTH_ENABLED is off.

Testing

Click Test Socket Connection to publish a test message through SocketCluster from the API container. A success response confirms the API can reach the SocketCluster server and publish events. If the test fails, check that:

  • The socket container is running (docker compose ps socket)
  • SOCKETCLUSTER_HOST and SOCKETCLUSTER_PORT in the application container match the socket container's actual hostname and port
  • No internal firewall rule is blocking container-to-container traffic on port 38000, or on the internal publish port 8001
  • SOCKETCLUSTER_AUTH_ENABLED and SOCKETCLUSTER_AUTH_KEY are identical on the application and socket containers. A key mismatch makes the socket server reject the API's signed publish requests; a switch that is on only for the socket server makes it refuse the API's legacy publishes in enforce mode.

Troubleshooting

WebSocket connections refused in the browser The origins list in SOCKETCLUSTER_OPTIONS must exactly match the Origin header sent by the browser, including the protocol — https://console.yourdomain.com, not just yourdomain.com. A mismatch causes the SocketCluster server to reject the upgrade request.

Events not appearing in real time If the event log is empty but the connection test passes, the issue is likely an origins mismatch on the browser side. Check the browser console for WebSocket errors and compare the reported origin against your SOCKETCLUSTER_OPTIONS value.

API broadcasts refused with Invalid origin: * The socket server logs this when the API publishes over the websocket (socket authentication off) without an Origin header while SOCKETCLUSTER_OPTIONS restricts origins. Set SOCKETCLUSTER_ORIGIN on the application, queue and scheduler containers (in Docker Compose, in the project .env) to an allowed origin such as https://console.yourdomain.com, then restart them.

Subscriptions rejected after enabling enforce mode A client is connecting without a token, or with a token for another company. Switch to SOCKETCLUSTER_AUTH_MODE=log, reproduce the problem, and read the socket_auth_deny lines: reason explains the denial (no_token, not_found, unknown_prefix, …) and client identifies the app. Outdated console, Navigator or Storefront builds connect anonymously and need upgrading.

POST /v1/socket/token returns 404 Socket authentication is off on the API: SOCKETCLUSTER_AUTH_ENABLED is not true on the application container, or SOCKETCLUSTER_AUTH_KEY is missing or shorter than 32 characters. This is expected until you turn it on. To turn it on, set both on every API container and the socket server, then restart them.

Real-time events stopped after switching to enforce The socket server is enforcing but the API still has SOCKETCLUSTER_AUTH_ENABLED off, so it publishes over the legacy websocket path, which is refused. Set SOCKETCLUSTER_AUTH_ENABLED=true on the application, queue and scheduler containers (or go back to log), then restart them.

Socket | Fleetbase