Skip to main content

Deployment Guide

OrbisID ships as two release packages. Choose the one that matches your environment.

Deploying to a cloud provider instead?

This page covers running the Docker Compose release packages on a single host. If you'd rather deploy onto managed cloud services, see AWS (CloudFormation), Azure (Bicep), or GCP (gcloud script) — all three pull the same orbisid/orbisid-backend/orbisid/orbisid-frontend Docker Hub images used here, just onto ECS Fargate + RDS, Container Apps + Flexible Server, or Cloud Run + Cloud SQL respectively.

Deployment Options​

PackageUse When
All-in-OneYou want a self-contained deployment with a bundled PostgreSQL database
External DatabaseYou have an existing managed PostgreSQL instance (AWS RDS, Azure Database, etc.)

Both packages contain:

  • docker-compose.yml - stack definition
  • .env.example - environment variable template
  • nginx.conf - reverse proxy configuration
  • images.tar.gz - bundled Docker images (OrbisID backend/frontend, plus PostgreSQL for the all-in-one package)

Both packages also start a local Ollama container by default, used by OrbisID's optional AI features. Unlike the images above, the Ollama image itself is not bundled in images.tar.gz — at several gigabytes, including it would push the release package past GitHub's release-asset size limit — so it's pulled from Docker Hub automatically the first time you run docker compose up -d. See AI Runtime (Ollama) for what this means and how to disable it.

All-in-One Deployment​

This is the simplest option. PostgreSQL runs as a container alongside OrbisID.

1. Extract and configure​

tar -xzf orbisid-<version>-all-in-one.tar.gz
cd orbisid-<version>-all-in-one
cp .env.example .env

Edit .env:

.env
# Image version and registry prefix (pre-filled by the release)
ORBISID_VERSION=<version>
BACKEND_IMAGE=orbisid/orbisid-backend
FRONTEND_IMAGE=orbisid/orbisid-frontend

# Generate with: openssl rand -base64 32
ENCRYPTION_KEY=<your-encryption-key>

# Bundled PostgreSQL
POSTGRES_DB=orbisid
POSTGRES_USER=orbisid
POSTGRES_PASSWORD=<strong-password>

# Spring profile
SPRING_PROFILES_ACTIVE=docker

2. Load Docker images​

docker load -i images.tar.gz

This only needs to be run once per install.

3. Start the stack​

docker compose up -d

4. Verify​

# Check all containers are healthy
docker compose ps

# Test the API
curl https://orbisid.example.local/api/v1/version

External Database Deployment​

Use this when connecting to a managed PostgreSQL instance.

1. Prepare the database​

Create a database and user on your PostgreSQL instance:

CREATE DATABASE orbisid;
CREATE USER orbisid WITH PASSWORD '<strong-password>';
GRANT ALL PRIVILEGES ON DATABASE orbisid TO orbisid;

OrbisID applies schema migrations automatically on startup via Flyway.

2. Extract and configure​

tar -xzf orbisid-<version>-external-db.tar.gz
cd orbisid-<version>-external-db
cp .env.example .env

Edit .env:

.env
ORBISID_VERSION=<version>
BACKEND_IMAGE=orbisid/orbisid-backend
FRONTEND_IMAGE=orbisid/orbisid-frontend

# Generate with: openssl rand -base64 32
ENCRYPTION_KEY=<your-encryption-key>

# External PostgreSQL connection
DB_HOST=your-postgres-host.example.com
DB_PORT=5432
DB_NAME=orbisid
DB_USERNAME=orbisid
DB_PASSWORD=<database-password>

SPRING_PROFILES_ACTIVE=docker

3. Load Docker images​

docker load -i images.tar.gz

This only needs to be run once per install.

4. Start the stack​

docker compose up -d

AI Runtime (Ollama)​

Both packages include and start an Ollama container by default, used by OrbisID's optional AI features (identity/PAM link suggestions, Account/Identity Type and Privilege Detection classification, narrative risk summaries, Access Graph natural-language query, and the OrbisAI chat assistant). Everything runs locally inside your own network — no data is ever sent to an external AI provider.

  • The AI feature toggle is separate from the container starting. Ollama running is not the same as AI being enabled — nothing calls out to it until an administrator turns AI on (via the one-time Initial Setup prompt on first login, or later in Administration > Settings > OrbisAI).
  • The Ollama container image itself is pulled from Docker Hub on first start, not bundled in images.tar.gz — at several gigabytes (it ships CUDA libraries even for CPU-only use), bundling it would exceed GitHub's per-file release-asset limit. Compose fetches it automatically the first time you run docker compose up -d; no separate docker load step is needed since it's a public image.
  • The default two chat/embedding models are then pulled automatically by a one-shot ollama-init container (qwen2.5:1.5b-instruct for chat/completions, nomic-embed-text for retrieval). Combined with the image pull above, the first docker compose up -d needs internet access and can take several minutes longer than subsequent starts. For a fully air-gapped install, run the stack once with internet access so the image and models are pulled and cached in the ollama_data volume, then copy that volume (and your loaded Docker images) to the offline host — or, once connectivity is available, pull the image and models manually (docker pull ollama/ollama:latest, docker exec <ollama-container> ollama pull qwen2.5:1.5b-instruct).
  • Don't want it at all? Stop both containers after the first docker compose up -d:
docker compose stop ollama ollama-init

This is safe to do at any time — the rest of the stack is unaffected, and AI-dependent pages simply stay hidden rather than erroring.

Enabling HTTPS​

For production deployments, TLS should be enabled. The nginx.conf included in the release package contains a commented-out HTTPS server block.

Option A: Terminate TLS at Nginx​

  1. Place your certificate files:
mkdir ssl
cp /path/to/fullchain.pem ssl/fullchain.pem
cp /path/to/privkey.pem ssl/privkey.pem
  1. Edit docker-compose.yml to expose port 443 and mount certificates:
nginx:
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl/fullchain.pem:/etc/nginx/ssl/fullchain.pem:ro
- ./ssl/privkey.pem:/etc/nginx/ssl/privkey.pem:ro
  1. Edit nginx.conf - uncomment the HTTPS server block and update server_name:
server {
listen 443 ssl http2;
server_name your.domain.com;

ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;

ssl_protocols TLSv1.2 TLSv1.3;
# ... rest of configuration
}
  1. Restart Nginx:
docker compose restart nginx

Option B: Terminate TLS upstream​

If you are using a load balancer (AWS ALB, Azure Application Gateway) or a CDN (Cloudflare) that handles TLS, the Nginx container can remain HTTP-only. Ensure the load balancer forwards traffic to port 80 on the Docker host.

Upgrading​

Your data is safe during upgrades

OrbisID stores all data in a named Docker volume (orbisid_postgres_data). Swapping Docker images never touches this volume — your database, scan history, accounts, credentials, and configuration are all preserved. The only command that destroys data is docker compose down -v, which explicitly removes volumes. Never use that flag when upgrading.

1. Back up​

Before upgrading, create a database dump as a precaution:

# All-in-one: dump the database from the running container
docker compose exec postgres pg_dump -U orbisid orbisid > backup-$(date +%Y%m%d).sql

# External database: use your standard backup process

Also keep a copy of your .env file (it contains your ENCRYPTION_KEY, which cannot be recovered if lost).

You do not need to back up the ollama_data volume. It only holds downloaded model weights, which are re-pulled automatically by the ollama-init container if the volume is ever recreated — it contains no user data.

2. Download and extract the new release package​

Download the new version from the OrbisID website and extract it alongside your current installation:

tar -xzf orbisid-<new-version>-all-in-one.tar.gz
cd orbisid-<new-version>-all-in-one

3. Copy your existing .env​

cp ../orbisid-<old-version>-all-in-one/.env .env

Update ORBISID_VERSION in .env to the new version:

ORBISID_VERSION=<new-version>

4. Load the new Docker images​

docker load -i images.tar.gz

This replaces the application images in your local Docker engine. The PostgreSQL image (and its data volume) is not affected.

5. Restart the stack​

Stop the old containers and start the new ones from the new directory:

# Stop the old stack (data volume is preserved)
docker compose -f ../orbisid-<old-version>-all-in-one/docker-compose.yml down

# Start the new stack
docker compose up -d

If you are upgrading in-place (same directory), a single command is enough:

docker compose up -d

Docker Compose detects that the image tags have changed and recreates only the affected containers. The postgres container is unchanged and its data volume is untouched.

Database migrations run automatically on startup. The backend applies any new Flyway migrations before accepting requests — you do not need to run SQL manually.

6. Verify​

# Check all containers are healthy
docker compose ps

# Confirm the new version is running
curl http://orbisid.example.local/api/v1/version

Stopping and Removing​

# Stop all containers (data is preserved in volumes)
docker compose down

# Start again later — all data is intact
docker compose up -d
Irreversible data loss

docker compose down -v removes all Docker volumes including the PostgreSQL data volume. This permanently deletes your database. Only use it when you intend to wipe the installation completely. Never use it when upgrading.

Container Health Checks​

ServiceHealth CheckInterval
PostgreSQLpg_isready10s
BackendGET /actuator/health30s
Frontend, NginxNone (Docker reports running, not healthy)-
OllamaNone — reachability is checked by the backend when an admin enables AI, not by Docker-
ollama-initOne-shot: pulls the default models, then exits 0. Expected to show Exited (0) in docker compose ps once done — that's success, not a crash.-

View health status with:

docker compose ps

Logs​

# All services
docker compose logs -f

# Single service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f nginx
docker compose logs -f postgres
docker compose logs -f ollama
docker compose logs -f ollama-init # model pull progress on first start