Deployment Guide
OrbisID ships as two release packages. Choose the one that matches your environment.
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
| Package | Use When |
|---|---|
| All-in-One | You want a self-contained deployment with a bundled PostgreSQL database |
| External Database | You have an existing managed PostgreSQL instance (AWS RDS, Azure Database, etc.) |
Both packages contain:
docker-compose.yml- stack definition.env.example- environment variable templatenginx.conf- reverse proxy configurationimages.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
- Linux
- macOS
- Windows
tar -xzf orbisid-<version>-all-in-one.tar.gz
cd orbisid-<version>-all-in-one
cp .env.example .env
tar -xzf orbisid-<version>-all-in-one.tar.gz
cd orbisid-<version>-all-in-one
cp .env.example .env
tar -xzf orbisid-<version>-all-in-one.tar.gz
cd orbisid-<version>-all-in-one
Copy-Item .env.example .env
Windows 10+ ships tar.exe natively, so this works unmodified from PowerShell.
Edit .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
- Linux
- macOS
- Windows
docker load -i images.tar.gz
docker load -i images.tar.gz
docker load -i images.tar.gz
This only needs to be run once per install.
3. Start the stack
- Linux
- macOS
- Windows
docker compose up -d
docker compose up -d
docker compose up -d
4. Verify
- Linux
- macOS
- Windows
# Check all containers are healthy
docker compose ps
# Test the API
curl https://orbisid.example.local/api/v1/version
# Check all containers are healthy
docker compose ps
# Test the API
curl https://orbisid.example.local/api/v1/version
# Check all containers are healthy
docker compose ps
# Test the API
Invoke-WebRequest -Uri 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
- Linux
- macOS
- Windows
tar -xzf orbisid-<version>-external-db.tar.gz
cd orbisid-<version>-external-db
cp .env.example .env
tar -xzf orbisid-<version>-external-db.tar.gz
cd orbisid-<version>-external-db
cp .env.example .env
tar -xzf orbisid-<version>-external-db.tar.gz
cd orbisid-<version>-external-db
Copy-Item .env.example .env
Windows 10+ ships tar.exe natively, so this works unmodified from PowerShell.
Edit .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
- Linux
- macOS
- Windows
docker load -i images.tar.gz
docker load -i images.tar.gz
docker load -i images.tar.gz
This only needs to be run once per install.
4. Start the stack
- Linux
- macOS
- Windows
docker compose up -d
docker compose up -d
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 rundocker compose up -d; no separatedocker loadstep is needed since it's a public image. - The default two chat/embedding models are then pulled automatically by a one-shot
ollama-initcontainer (qwen2.5:1.5b-instructfor chat/completions,nomic-embed-textfor retrieval). Combined with the image pull above, the firstdocker compose up -dneeds 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 theollama_datavolume, 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:
- Linux
- macOS
- Windows
docker compose stop ollama ollama-init
docker compose stop ollama ollama-init
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.
- See Requirements for the resource impact of running Ollama, and AI Assistant (OrbisAI) for what each feature does and how to configure the model/base URL/timeout.
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
- Place your certificate files:
- Linux
- macOS
- Windows
mkdir ssl
cp /path/to/fullchain.pem ssl/fullchain.pem
cp /path/to/privkey.pem ssl/privkey.pem
mkdir ssl
cp /path/to/fullchain.pem ssl/fullchain.pem
cp /path/to/privkey.pem ssl/privkey.pem
New-Item -ItemType Directory -Force ssl
Copy-Item C:\path\to\fullchain.pem ssl\fullchain.pem
Copy-Item C:\path\to\privkey.pem ssl\privkey.pem
- Edit
docker-compose.ymlto 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
- Edit
nginx.conf- uncomment the HTTPS server block and updateserver_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
}
- Restart Nginx:
- Linux
- macOS
- Windows
docker compose restart nginx
docker compose 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
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:
- Linux
- macOS
- Windows
# 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
# 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
# All-in-one: dump the database from the running container
docker compose exec postgres pg_dump -U orbisid orbisid > "backup-$(Get-Date -Format yyyyMMdd).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:
- Linux
- macOS
- Windows
tar -xzf orbisid-<new-version>-all-in-one.tar.gz
cd orbisid-<new-version>-all-in-one
tar -xzf orbisid-<new-version>-all-in-one.tar.gz
cd orbisid-<new-version>-all-in-one
tar -xzf orbisid-<new-version>-all-in-one.tar.gz
cd orbisid-<new-version>-all-in-one
Windows 10+ ships tar.exe natively, so this works unmodified from PowerShell.
3. Copy your existing .env
- Linux
- macOS
- Windows
cp ../orbisid-<old-version>-all-in-one/.env .env
cp ../orbisid-<old-version>-all-in-one/.env .env
Copy-Item ..\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
- Linux
- macOS
- Windows
docker load -i images.tar.gz
docker load -i images.tar.gz
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:
- Linux
- macOS
- Windows
# 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
# 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
# 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:
- Linux
- macOS
- Windows
docker compose up -d
docker compose up -d
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
- Linux
- macOS
- Windows
# Check all containers are healthy
docker compose ps
# Confirm the new version is running
curl http://orbisid.example.local/api/v1/version
# Check all containers are healthy
docker compose ps
# Confirm the new version is running
curl http://orbisid.example.local/api/v1/version
# Check all containers are healthy
docker compose ps
# Confirm the new version is running
Invoke-WebRequest -Uri http://orbisid.example.local/api/v1/version
Stopping and Removing
- Linux
- macOS
- Windows
# Stop all containers (data is preserved in volumes)
docker compose down
# Start again later — all data is intact
docker compose up -d
# Stop all containers (data is preserved in volumes)
docker compose down
# Start again later — all data is intact
docker compose up -d
# Stop all containers (data is preserved in volumes)
docker compose down
# Start again later — all data is intact
docker compose up -d
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
| Service | Health Check | Interval |
|---|---|---|
| PostgreSQL | pg_isready | 10s |
| Backend | GET /actuator/health | 30s |
| Frontend, Nginx | None (Docker reports running, not healthy) | - |
| Ollama | None — reachability is checked by the backend when an admin enables AI, not by Docker | - |
ollama-init | One-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:
- Linux
- macOS
- Windows
docker compose ps
docker compose ps
docker compose ps
Logs
- Linux
- macOS
- Windows
# 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
# 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
# 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