Skip to main content

Docker Deployment

Deploy the full FHIR terminology server as a Docker container. Builds lookup.duckdb from UMLS RRF using your own NLM API key — fully license-compliant.

Quick start​

# One-command rebuild + restart (stops existing container if any,
# waits for /health, prints startup banner)
scripts/rebuild_fhir_docker.sh

# Or manual:
docker build -f deploy/hf-spaces/fhir-server/Dockerfile -t medterm4ds-fhir .
docker run -p 8001:7860 \
-e UMLS_API_KEY=your_umls_api_key \
-v fhir4ds-data:/data \
medterm4ds-fhir

First start takes ~10 minutes (downloads UMLS RRF + builds DB + downloads search indexes). Subsequent starts with cached volume: ~30 seconds. The image ships with a HEALTHCHECK hitting /health every 30s — docker ps shows health status, HF Spaces may pick this up.

Environment variables​

Required:

VariableDescription
UMLS_API_KEYNLM UMLS API key — used to download UMLS RRF and build lookup.duckdb.

Optional (server bind):

VariableDefaultDescription
MEDTERM4DS_API_HOST127.0.0.1 (local) / 0.0.0.0 (HF Spaces)Bind host. Docker forces 0.0.0.0 for HF Spaces reachability — see SECURITY.md for auth implications.
MEDTERM4DS_FHIR_API_PORT8001 (local) / 7860 (HF Spaces)Bind port. HF Spaces requires 7860.

Optional (data provisioning):

VariableDefaultDescription
HF_TOKENunsetHF token — only needed for private datasets.
UMLS_RELEASE2026AAUMLS Metathesaurus release version.
MEDTERM4DS_DATA_DIR/dataWhere lookup.duckdb and downloaded derived data live.
MEDTERM4DS_HF_DATASETjoelmontavon/medterm4ds-dataHF dataset repo for BM25 + SapBERT + patient_friendly JSONs.

Optional (search + extraction assets):

VariableDefaultDescription
MEDTERM4DS_SEARCH_INDEX_DIR(built-in default)Directory with <category>_bm25.json. $search lexical/hybrid returns 503 if missing.
MEDTERM4DS_EMBEDDING_MODEL_DIR(built-in default)SapBERT model dir. $search semantic/hybrid returns 503 if missing.
MEDTERM4DS_LAYOUTautoArtifact cache layout: auto prefers the split layout (models/<space>/ + data/<revision>/, validated manifests); legacy forces the flat legacy layout (kill-switch).
MEDTERM4DS_DATA_REVISIONlatestPin the split-layout data revision (e.g. cdb_2026_09_07) instead of floating to the latest publish.
MEDTERM4DS_EMBEDDING_SPACElatest acceptedPin the SERVING embedding space (e.g. esp_f6c5c18d5f3ee3b5). A set-but-unknown value FAILS LOUD at load naming the accepted values (no silent fallback — rotation-safe); unset = the default serving space. cache-info reports serving_space + serving_space_source.
MEDTERM4DS_SEMANTIC_INDEX_DIRmd5 bridgeOverride the per-category FAISS index dir. Default reuses the legacy semantic/ indexes when weights + tokenizer are byte-identical to the split model.
MEDTERM4DS_FHIR4PX_BASELINE(built-in default)Directory with patient_friendly_<source>.json. $lookup skips patient-friendly properties if missing.

Optional (request caps):

VariableDefaultDescription
FHIR_VS_MAX_DEPTH5Cap on $expand?fhir_vs=isa descendant depth. Covers clinical value-set definitions; deeper needs pre-computed closure.
MEDTERM4DS_MAX_EXTRACT_TEXT_CHARS100000Cap on $extract input length (~50 pages of clinical text).

Optional (operational):

VariableDefaultDescription
MEDTERM4DS_MEMORY_PROFILElow (in Docker)DuckDB memory profile (low, balanced, high).
MEDTERM4DS_DEVICEautotorch device for GLiNER/SapBERT inference (auto, cpu, cuda, cuda:<n>, mps). GPU use in Docker requires the nvidia container runtime; with it, auto picks the GPU automatically.
MEDTERM4DS_EXTRACT_BATCH_SIZE32GLiNER inference batch size (sentences per forward pass) when extract() is called with a list of texts.
MEDTERM4DS_EMBED_BATCH_SIZE64SapBERT queries per forward pass in canonical search/resolve batches. Raise on large-GPU hosts.
MEDTERM4DS_DISABLE_CVX_GROUPSunsetIf set, disables CVX-group resolution from the vendored VG.txt (no runtime network fetch since 0.0.4).
MEDTERM4DS_NER_ALLOW_UNCALIBRATEDunsetIf 1, loads a GLiNER config whose calibration id is not in the acceptance registry (warns with both ids).

The startup banner prints every tunable env var with its current value.

Data provisioning​

DataHowSize
lookup.duckdbBuilt from UMLS RRF (your NLM key)217 MB
patient_friendly JSONsDownloaded from HF (derived)225 MB
BM25 indexesDownloaded from HF (derived)167 MB
SapBERT + FAISSDownloaded from HF (derived)2.5 GB

Persistent storage​

docker volume create fhir4ds-data
docker run -p 8001:7860 -e UMLS_API_KEY=xxx -v fhir4ds-data:/data medterm4ds-fhir

The volume name fhir4ds-data is the legacy name (renaming would lose the cached lookup.duckdb — 8-min rebuild). Keep it as-is.

Hugging Face Spaces​

The Dockerfile is HF Spaces compatible (Docker SDK, port 7860). Set UMLS_API_KEY (required) and HF_TOKEN (only if your HF dataset is private) as Space secrets.

Auth note: HF Spaces does not authenticate inbound requests to a public Space. Anyone with the Space URL can call $lookup, $extract, $search, etc. against your UMLS-API-key-built DB. For non-personal deployments, use a private Space or front the deployment with an authenticating proxy. See SECURITY.md for the full threat model.