Prerequisites
- Linux, macOS, or Windows with WSL 2
- Docker Engine 20.10+ and Docker Compose v2+
- On Apple Silicon or other arm64 hosts, Docker must emulate linux/amd64 (Docker Desktop Rosetta or QEMU). CaseBender application images and the bundled ClamAV scanner are amd64-only. First boot can take several minutes while the web container runs database migrations and seed data.
- Node.js 20+ on the host (
./casebender setup,preflight,up,upgrade, and the canary check invoke Node;initalone does not) - OpenSSL
- Cosign (bundle signature verification only; not required to run
initorup) - 8 GB RAM minimum, 16 GB recommended (web, API, workers, PostgreSQL, Redis, and the bundled ClamAV scanner)
- Ports 80 and 443 free on the host
- For production: a DNS name and trusted TLS certificate for the CaseBender host
- Internet access to download the public Community bundle and container images, or an approved process for mirroring the release’s exact image digests
./casebender up pulls the
pinned tags from the registry in release.env. If that registry requires
authentication, run docker login for it before up.
Do not copy credentials from this guide into an installation. CaseBender
generates installation-specific secrets.
1. Download and verify the Community bundle
The CaseBender source repository is private and is not part of the customer installation process. The public, source-free bundle contains the production Compose definition, thecasebender management command, preflight and canary
checks, Nginx configuration, and pinned release metadata.
Download the latest Community on-premises bundle
Source-free Docker Compose installation bundle
shasum -a 256 -c instead of each sha256sum -c.
The signed archive contains the same release-manifest.json; compare it with
the separately downloaded manifest and retain it with your deployment records.
It records the exact source commit and signed digest for every container image
in the release.
The Community download does not currently include an offline image archive.
For an air-gapped installation, mirror or export all seven exact image digests
from release-manifest.json through your approved software-import process and
load them into Docker or your internal registry before running
./casebender up --offline.
2. Initialize the installation
Guided setup (recommended)
On a terminal, one command prompts for the public HTTPS URL, writes.env,
starts the stack, and prints a boxed one-time setup code:
--yes or CASEBENDER_NONINTERACTIVE=1 to skip prompts. Air-gapped hosts
that already have images loaded use ./casebender setup --offline.
Default local volume
The first install uses local file storage. License (community or enterprise) does not change that. Non-interactive initialize with no storage variables:STORAGE_PROVIDER=local, stores files on a named Docker volume at
/data, and starts a bundled ClamAV scanner on the internal Compose network.
An in-app banner notes that files live on this host. You can keep this after
applying an enterprise license, or switch later to object storage.
Optional object storage
GCS_BUCKET/GCS_PROJECT_ID with ADC. Azure uses
AZURE_STORAGE_ACCOUNT/AZURE_CONTAINER with Managed Identity. A mounted
STORAGE_CONFIG_FILE or inline STORAGE_CONFIG_JSON can define separate
quarantine, records, and ephemeral profiles. MinIO is not a supported provider
and is not embedded in Compose.
Initialization:
- reads the pinned image version and registry from the bundle’s
release.env; - creates
.envwith unique authentication, database, Redis, and OpenSearch secrets while preserving the supplied storage configuration; - keeps secrets out of command output;
- prepares the one-time local activation state; and
- refuses to overwrite an existing
.envor reset an installation.
.env in your approved secret store. Never commit it or send it through
email or chat.
Then set the public HTTPS origin if you did not use ./casebender setup.
Non-interactive init writes https://localhost, which is enough only for a
local browser override. Sign-in cookies and later OAuth integrations need the
real URL:
Failed to connect to database while waiting for host db,
this release is older than the Postgres service rename. Add the following to
.env and to the web service environment in docker-compose.prod.yml,
then run ./casebender up again:
3. Install TLS certificates
./casebender init already writes a temporary self-signed certificate at:
https://localhost after ./casebender init is
expected. Proceed for evaluation, then replace the certificate before
production.
4. Run production preflight
STORAGE_PROVIDER=local). Object-storage profiles must use
canonical variables and HTTPS endpoints. Mounted storage profile files must be
absolute paths, valid JSON, and inaccessible to group/other users (mode 0600).
5. Start CaseBender
./casebender setup. This pulls only the pinned
images identified by release.env; it does not clone or build the private
source repository. First up prints numbered steps while the web container
runs migrations and seed (often several minutes on ARM under amd64 emulation)
and then prints a boxed one-time setup code with the full /setup URL. If
Compose exits before that, the /setup page shows Setup code required
until you run ./casebender activation-code against a healthy web container.
Nginx starts only after the web process answers GET /api/health. Next.js
printing Ready is not the same as storage /api/health/ready. If web logs
already show the server started but Compose still shows casebender-web as
Waiting (and nginx never starts), start the proxy:
healthcheck URL must be /api/health, not /api/health/ready.
If ./casebender activation-code fails with Cannot find package 'zod', Node
ESM cannot see pnpm’s nested copy. Create a top-level symlink, then issue the
code. NODE_PATH does not work for this ESM CLI.
zod@ version differs, pick the path from:
6. Complete one-time activation
After./casebender up or ./casebender setup prints the boxed setup code,
open the URL shown next to Open: (from NEXTAUTH_URL) on the same host.
To reissue a code:
CODE= line for
logs. The code is at least 32 characters, expires after 30 minutes, allows
five failed attempts, and cannot be reused after activation.
./casebender activation-code again; the previous code is
invalidated.
7. Verify the deployment
- the administrator can sign in;
- another organization cannot access its cases, alerts, tasks, attachments, or audit records;
- API keys cannot request scopes beyond the owner’s permissions;
- integration destinations use HTTPS and approved egress;
- backup and restore procedures work.
Clean start on a new host
Use this sequence when replacing a legacy install with an empty product. It creates a new database, new encryption keys, and a new first administrator. Existing cases, users, and integrations are not imported.- Leave the legacy directory untouched. Extract this bundle into a new directory so Docker Compose does not reuse the old project name or volumes.
- Confirm Node.js 20+ (
node -v) and that ports 80 and 443 are free. ./casebender init(no storage variables for local volume + bundled ClamAV).- Edit
.envand setNEXTAUTH_URL,NEXTAPP_URL, andOAUTH_ALLOWED_ORIGINStohttps://<your-dns>. - Replace
deploy/nginx/ssl/with a trusted certificate, or accept a browser warning for evaluation only. ./casebender preflightthen./casebender up../casebender activation-codeand openhttps://<your-dns>/setup.
docker-compose.yml directory, and do not
run ./casebender init where an existing .env or named volumes already belong
to a live install. init refuses to overwrite .env; deleting that file to
force init would generate new database passwords against leftover pgdata.
Postgres only reads POSTGRES_PASSWORD on first initialization, so the new
.env cannot log in. init now refuses when pgdata already exists.
If you already generated a new .env against leftover volumes, keep that
.env and reset data:
Existing installations
When an existing CaseBender database is upgraded, the compatibility migration marks itACTIVE. Existing users, passwords, roles, organizations, cases, and
API keys remain unchanged. The setup page does not appear and seeding does not
create or reset an administrator.
Take a verified backup and follow Upgrading CaseBender.
Connected hosts run ./casebender upgrade --version 1.0.9. Air-gapped hosts
apply a local archive with
./casebender upgrade --offline ./casebender-onprem-v1.0.9.tar.gz.
Do not copy release.env or Compose files by hand. If the current deployment uses a legacy
docker-compose.yml with app, db, or embedded MinIO services, use
Migrate a Legacy Docker Compose Installation
instead of treating it as a routine upgrade. Preserve the existing .env,
Compose project name, named volumes, attachment storage, and cryptographic
keys. Never run ./casebender init against an existing installation.
On-premises private integrations
Outbound integrations require HTTPS and reject loopback, link-local, metadata, and private destinations by default. To permit a specific internal integration, add only its exact hostname to:Useful commands
docker compose down -v on an installation that contains data. A
clean reinstall that should wipe Postgres uses
./casebender down --purge-volumes --confirm.
Next steps
- First-run setup
- License
- Hardening guide
- Upgrading CaseBender
(
./casebender upgrade --version 1.0.9or./casebender upgrade --offline ./casebender-onprem-v1.0.9.tar.gz) - API keys