Configuration: the basics
Deployment configuration is environment variables in .env, created from
env.template (cp env.template .env, or by scripts/setup.sh).
env.template is the authoritative, commented list; this page covers the
variables most deployments touch. Everything else is on
Advanced configuration.
Environment variables describe the deployment: ports, GPUs, model names, mounts, limits. Anything that belongs to one dataset is not an environment variable: classes, keymaps, prompt packs, region profiles, VLM endpoint choice and strategy defaults are stored per project and edited through the API. See Where configuration lives.
.envdocker compose interpolates .env into docker-compose.yml (ports, GPU
ids, image tags). The Python app reads the OP_* variables from its
process environment. make also reads .env (-include .env). .env
values are not shell-expanded, so one variable can't reference
another.
OP_* variables are read at process startCuration routers build their prefix when src.main is imported, and
workers read their settings once at startup. Changing any OP_* variable
needs a container recreate, not a restart. ./openprocessor start (or
make up and make curation-up in a checkout) recreates every service whose
configuration changed. For one service, run
docker compose -p <project> up -d --force-recreate <service>.
Where configuration lives
| Layer | Holds | Edited with |
|---|---|---|
.env (this page and Advanced) | Ports, GPU ids, model names, source mounts, limits, the paths projects are created under | A text editor, then recreate the container |
| Project record | A project's OpenSearch index names, class registry, export root, upload root, bake-off roots and job directories. Fixed when the project is created | POST /curation/projects |
Project config store (a configs index per project) | Prompt packs, region profiles, the active VLM endpoint, the keymap, strategy defaults, with revisions and rollback | /curation/projects/{project}/prompt_packs, /region_profiles, /vlm/endpoints, /keymap, /settings |
Global config store (op_global_configs) | The VLM endpoint registry, shared by every project | /curation/vlm/endpoints |
A project's paths are resolved once, at creation, from the variables in
Projects and stored in its record. Changing
those variables later does not move an existing project. There are no
environment variables for individual index names, the class registry file,
the export root or the upload root: every project owns
{OP_PROJECT_INDEX_PREFIX}{slug}__{role} indexes and its own directories.
Details are on Projects and
Settings and config store.
GPU profile and performance
The installer and scripts/setup.sh write these keys from the selected GPU
profile (minimal, standard or full; see GPU sizing).
The profile is applied when it is chosen: it sets the Triton model
instance counts and batch size in the model configs, and decides whether GPU
decode is on (OP_INGEST_GPU_DECODE, the one profile-driven key the app
acts on). The API runs 32 uvicorn workers and every service that sets
shm_size uses 8g, whatever the profile.
| Variable | Default | Meaning |
|---|---|---|
GPU_PROFILE | standard | minimal (6-8 GB), standard (12-24 GB), full (40 GB+). Read by ./openprocessor gpu plan and the model setup, not by compose |
GPU_ID | 0 | GPU the setup scripts measure for the profile |
OP_INGEST_GPU_DECODE | 1 for full, 0 for minimal and standard | Decode large photos on the GPU; costs about 8.5 GB more VRAM on the Triton card per gpu_image_prep instance (full: two) |
OPENSEARCH_HEAP | 2g in env.template | OpenSearch JVM heap. The installer sets it to half of host RAM, between 2 and 30 GB, and never overwrites a value you set. Raise it for more projects: about 1 GB per 20 shards |
Choose the profile at install time: pass --profile NAME to the installer,
or run scripts/setup.sh --profile=NAME --force in a checkout (--force
rewrites .env, keeping your OPENSEARCH_HEAP). Then check the result with
./openprocessor gpu plan. In a checkout, ./openprocessor profile <name>
switches an existing install: it rewrites the Triton configs and sets
GPU_PROFILE and OP_INGEST_GPU_DECODE in .env.
GPU ids
Read by docker-compose.yml directly. Each GPU-using service has its own
variable; see GPU sizing.
| Variable | Default | Service |
|---|---|---|
TRITON_GPU_ID | 0 (a comma list such as 0,2 also runs the PE image encoder on the other cards) | triton-server |
API_GPU_ID | 0 | api (torch fallbacks, CUDA-side preprocessing) |
EVALUATOR_GPU_ID | 0 | curation-evaluator |
SEGMENTER_GPU_ID | 0 | segmenter |
VLM_GPU_ID | 0 | vlm |
OP_TRAIN_GPU_ORDER | 0 | curation-trainer (drives both its device_ids and its host-to-local id mapping) |
Ports and bind address
| Variable | Default | Service |
|---|---|---|
API_PORT | 4603 | API (all endpoints) |
TRITON_HTTP_PORT / TRITON_GRPC_PORT / TRITON_METRICS_PORT | 4600 / 4601 / 4602 | Triton |
OPENSEARCH_PORT | 4607 | OpenSearch REST |
OPENSEARCH_DASHBOARDS_PORT | 4608 | OpenSearch Dashboards (monitoring profile) |
PROMETHEUS_PORT / GRAFANA_PORT / LOKI_PORT | 4604 / 4605 / 4606 | Monitoring profile |
DCGM_PORT | 4610 | DCGM GPU metrics |
MLFLOW_PORT | 4609 | MLflow (training profile) |
SEGMENTER_PORT | 4611 | Segmenter (segmenter profile) |
VLM_PORT | 4612 | In-compose VLM (vlm profile) |
OP_BIND_ADDRESS | 127.0.0.1 | Address every published port binds to. The API has no authentication, so set 0.0.0.0 (or a non-loopback address) only behind a reverse proxy that does; see Security |
OP_UI_BIND_ADDRESS | value of OP_BIND_ADDRESS | Publish address for only Grafana, Prometheus, OpenSearch Dashboards and MLflow, so LAN browsers can follow the resource links without exposing OpenSearch, Triton, the VLM or segmenter APIs. Grafana's default login is admin/admin (set GF_SECURITY_ADMIN_PASSWORD first); MLflow and Prometheus have no auth |
Stack isolation
| Variable | Default | Meaning |
|---|---|---|
COMPOSE_PROJECT_NAME | openprocessor | Compose project name: container names, network and volumes. Not the same thing as a curation project |
OP_IMAGE_REPO / OP_IMAGE_TAG | published repo / the checkout's VERSION | Image names for every built service; give a second clone its own tag |
See Running a second, isolated stack.
Logging
| Variable | Meaning |
|---|---|
DEBUG | 1 for verbose logging |
Core model selection
| Variable | Meaning |
|---|---|
YOLO_MODEL | Default detector for /detect and /analyze, e.g. yolo26_small_trt (any request can still pass model_name) |
The other Triton model names (FACE_DETECT_MODEL, ARCFACE_MODEL,
CLIP_*_MODEL, OCR_*_MODEL, PE_*_MODEL) are on
Advanced configuration.
The minimum for curation
Everything curation-related is optional, and unset variables fall back to
the defaults in CurationConfig.from_env(). These are the ones a first
curation deployment actually sets:
| Variable | Why |
|---|---|
OP_INGEST_PRIMARY_DETECTOR_MODEL | Required for ingest (it 503s without one): the Triton end2end model that proposes items, e.g. yolov11_small_trt_end2end |
OP_INGEST_PRIMARY_CLASS_IDS | Retired and ignored with a warning. Narrow ingest per project with the ingest policy instead |
OP_INGEST_PRIMARY_ASSIGNS_CLASS | false (default): detections are unlabeled proposals. true only if the detector was trained on your class registry |
OP_SOURCE_ROOT_HOST | Host directory mounted read-only at /data/source in three services: api, curation-detection-worker and curation-auto-label-worker. A source checkout defaults to ./data/source; the installer writes ./data. Recreate all three after changing it |
OP_VLM_URL, OP_VLM_MODEL, OP_VLM_API_KEY | An OpenAI-compatible /v1/chat/completions endpoint. This defines the built-in env VLM endpoint, which a project uses only after it activates it; OP_VLM_MODEL is required whenever OP_VLM_URL is set. More endpoints are registered through the API; see VLM selection |
OP_SEGMENTER_URL | e.g. http://segmenter:8000; empty makes the cascade's segmenter leg a clean no-op |
HF_TOKEN | Needed by the segmenter (gated SAM 3 weights) and for gated VLM weights |
OP_SEMANTIC_SEARCH_ENABLED, OP_SCORES_ENABLED, OP_SELECT_DIVERSE_ENABLED, OP_VIZ_PROJECTION_ENABLED | Feature flags, off by default (set to 1) |
OP_MLFLOW_PUBLIC_URL | Browser-reachable MLflow URL, so served run links work |
Classes are not set here. Each project has its own class registry, created
empty; add classes with POST /curation/projects/{project}/classes (see the
Quick start) or import a labeled
dataset.
Region detection profiles, prompt packs and the active VLM are stored per
project and managed through the API, not through .env. The
OP_REGION_PROFILE_PATH and OP_PROMPT_PACK_PATH variables only supply
the deployment default a project uses until it activates its own; see
Advanced configuration.
Clustering and training knobs are there too.