Multi-Server Deployment¶
This guide covers deploying ubTrace services across different servers or network configurations.
Architecture Overview¶
ubTrace consists of the following services that need to communicate:
API server (NestJS backend) – serves the REST API
Frontend (Next.js) – serves the web application
Keycloak – handles authentication (OIDC)
PostgreSQL – application database
Elasticsearch – search and analytics indexing
Redis – caching and session management
In the default Docker Compose setup, all services run on the same host and communicate via the internal Docker network. For multi-server deployments, the key challenge is configuring the public-facing URLs correctly.
URL Configuration¶
Three sets of URLs must be configured:
Keycloak URLs – the OIDC issuer must be reachable from both the user’s browser and the API server.
API server URL – the frontend needs to reach the API, and Keycloak needs to send backchannel logout requests to it.
Frontend URL – used for post-login redirects.
# .env -- adjust to your actual hostnames/IPs
# Keycloak (must be reachable from browser AND ubtrace-api)
KC_HOSTNAME=https://auth.yourdomain.com
OIDC_ISSUER=https://auth.yourdomain.com/realms/ubtrace
# API server (must be reachable from browser AND keycloak)
API_SERVER_PUBLIC_URL=https://api.yourdomain.com
# Frontend (used for redirects after login)
FRONTEND_PUBLIC_URL=https://ubtrace.yourdomain.com
FRONTEND_UBT_URL=https://ubtrace.yourdomain.com
Deployment Scenarios¶
Single Host (Docker Compose)¶
The default docker-compose-prod.yml runs all services on one machine.
No special URL configuration is needed beyond setting passwords.
docker compose -f docker-compose-prod.yml up -d
Split Services (Multiple Hosts)¶
When services run on different machines (e.g., database on a dedicated server):
Remove the service from your local
docker-compose-prod.ymlPoint the relevant environment variables to the remote host
Example – external PostgreSQL:
# .env
DATABASE_URL=postgresql://ubtrace:password@db-server.internal:5432/ubtrace
Example – external Elasticsearch:
# In the ubtrace-api environment section of docker-compose-prod.yml
ELASTICSEARCH_NODE: 'http://es-server.internal:9200'
Reverse Proxy¶
For production, place a reverse proxy (nginx, Traefik, Caddy) in front of the services to handle TLS termination:
Browser --> Reverse Proxy (TLS) --> Frontend (:7155)
--> API Server (:7150)
--> Keycloak (:7181)
Ensure that the KC_HOSTNAME, API_SERVER_PUBLIC_URL, and FRONTEND_PUBLIC_URL
variables use the external HTTPS URLs that the browser will access.
Troubleshooting¶
- OIDC errors after login
Verify
OIDC_ISSUERis reachable from both the user’s browser and the API server containerInside the Docker network, the API server uses
OIDC_BASE_URL(http://ubtrace-keycloak:8080/...) for server-to-server communication
- Frontend cannot reach API
Check that
UBTRACE_API_URLin the frontend environment points to the correct API server URLIf behind a reverse proxy, ensure the
/apipath is forwarded correctly
- Services not starting
Check service logs:
docker compose logs <service-name>Verify all dependent services are healthy:
docker compose psCheck firewall rules and network connectivity between servers