Choosing a Deployment Path
Abrq DIP is self-hosted software. You run every component — the API, the background workers, the scheduler, the web frontend, and (optionally) the data tier — inside your own infrastructure. There are three supported ways to deploy it, and they are not interchangeable: each has its own artifacts, its own configuration surface, and its own upgrade story. Pick one deliberately.
The three paths#
| Path | Use it for | Artifacts | Guide |
|---|---|---|---|
| Kubernetes (Helm) | The primary production path. Multi-replica API and workers, autoscaling, disruption budgets, managed or in-cluster data tier. | Helm chart at deploy/helm/abrq-dip/ (vendored subcharts included) |
Kubernetes deployment |
| Docker Compose | Single-VM production installs and local development. One host, one compose file. | docker-compose.prod.yml and docker-compose.dev.yml in the repository root |
Docker Compose deployment |
| Air-gapped release bundle | Offline installs with zero internet egress. The offline variant of the Compose path: same single-host shape, but pre-built image tarballs and a vendor-issued license, delivered as one archive. | abrq-dip-<VERSION>.tar.gz from your vendor |
Air-gapped installation |
How to choose:
- If you operate a Kubernetes cluster, use the Helm chart. It is the only path with horizontal scaling, pod disruption budgets, and rolling upgrades.
- If you have one Linux VM and internet access to build or pull images,
use
docker-compose.prod.yml. - If the target environment has no internet access, use the release bundle. Everything it needs — including the database and Redis images — ships inside the tarball.
Note. The development compose file (
docker-compose.dev.yml) is for working on Abrq DIP itself: it bind-mounts source code, exposes the database port, and bakes in insecure defaults. Never use it as a production starting point.
Preparation common to all paths#
Whichever path you pick, the same runtime inputs must exist before first start.
Secrets to generate#
| Secret | Requirement | Purpose |
|---|---|---|
ABRQ_MASTER_KEY |
A Fernet key (32 url-safe base64-encoded bytes). Required — the backend refuses to start without it. | Encrypts every stored secret (connector credentials, SMTP passwords, SSO configs) at rest in the framework database. |
ABRQ_JWT_SECRET |
At least 32 characters of randomness in production. Required. | Signs user session tokens. |
ABRQ_INITIAL_ADMIN_PASSWORD |
A strong password of your choosing. Production refuses the literal default. | Seeds the first admin account on an empty database. The user is forced to change it at first login. |
ABRQ_CORS_ALLOWED_ORIGINS |
The exact origin(s) your users load the UI from, comma-separated — for example https://abrq.example.com. |
Browser cross-origin policy for the API. Production requires an explicit value. |
Generation commands (the Fernet and token generators run inside the backend image so you do not need a local Python):
# ABRQ_MASTER_KEY — Fernet key
docker run --rm abrq-dip-backend:<VERSION> python -c \
"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# ABRQ_JWT_SECRET — url-safe random
docker run --rm abrq-dip-backend:<VERSION> python -c \
"import secrets; print(secrets.token_urlsafe(48))"
# Database password — random hex
openssl rand -hex 32
Warning. Keep
ABRQ_MASTER_KEYsafe and backed up. It decrypts every stored connector secret; losing it makes stored connection credentials unrecoverable. See backup and restore.
License file#
Production deployments (ABRQ_ENV=prod) verify a vendor-signed
license.json at startup and refuse to start if it is missing, malformed,
signature-invalid, or expired. The backend reads it from the path in
ABRQ_LICENSE_FILE (default /var/abrq-dip/license.json) on the API,
worker, and beat processes. There is no upload UI — the license is a file
you place before starting. Details, including hardware-bound licenses:
installing a license.
Database migrations — what the migrator does#
Every path runs the same migration mechanism before the application
serves traffic: a migrator process that
- waits for the framework database to accept connections,
- takes a PostgreSQL advisory lock (so exactly one runner migrates while any concurrent replicas block, then see the schema already applied),
- runs
alembic upgrade head, and exits.
Under Kubernetes this runs as an init container on every API, worker, and
beat pod; under Compose it is a one-shot migrator service the other
services depend on. You never run migrations by hand on any path.
After installation#
Every path ends the same way: GET /health returns
{"status": "ok"} with both dependencies (framework_db, redis)
reporting ok, you log in with the initial admin credentials, and the UI
forces a password change. From there, continue with
configuration and take a first metadata backup
(upgrade and rollback explains why before-anything
backups matter).