feat(pii): env-driven uvicorn worker count (PII_WORKERS) (#5457)

* feat(pii): env-driven uvicorn worker count (PII_WORKERS)

Launch the Presidio service with --workers from the PII_WORKERS env var so one
image scales per task size (set PII_WORKERS = the task's vCPU count) without a
rebuild. `sh -c exec` expands the var while keeping uvicorn as PID 1 for clean
SIGTERM. Defaults to 1, so local/self-hosted is unchanged. Each worker loads the
spaCy models independently (~3.3GB measured), so task memory must be sized to
PII_WORKERS x ~3.3GB + overhead (set in infra alongside PII_WORKERS).

* harden(pii): quote PII_WORKERS expansion + raise healthcheck start-period for multi-worker

- Quote ${PII_WORKERS} so a malformed value fails uvicorn arg-parsing instead of
  being shell-interpreted (verified: '1; echo X' rejected as non-integer, X not run)
- Bump HEALTHCHECK start-period 180s -> 300s: N workers load the spaCy models in
  parallel, stretching cold start beyond the single-worker case
This commit is contained in:
Theodore Li
2026-07-06 21:23:48 -04:00
committed by GitHub
parent 719179258c
commit 07a12249f5
+11 -4
View File
@@ -42,9 +42,16 @@ USER pii
# 5001 avoids colliding with the app's 3000 in local/compose runs on one host.
EXPOSE 5001
# start-period is generous: five large spaCy models load at import before
# /health responds. Tune against measured cold-start once built.
HEALTHCHECK --interval=30s --timeout=5s --start-period=180s --retries=3 \
# start-period covers the model cold start. With PII_WORKERS>1 each worker loads
# the five spaCy models independently and in parallel, so allow generous headroom
# (memory-bandwidth contention stretches the wall-time beyond the single-worker case).
HEALTHCHECK --interval=30s --timeout=5s --start-period=300s --retries=3 \
CMD curl -fsS http://localhost:5001/health || exit 1
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "5001"]
# Worker count is env-driven so ONE image scales per task size: set PII_WORKERS to
# the task's vCPU count (each worker loads the models independently, ~3 GB each, so
# size task memory ≈ PII_WORKERS × 3 GB + overhead). Defaults to 1 for local/small.
# `sh -c exec` expands the env var while keeping uvicorn as PID 1 for clean SIGTERM.
# Quote the expansion so a malformed PII_WORKERS fails uvicorn arg-parsing rather
# than being interpreted by the shell.
CMD ["sh", "-c", "exec uvicorn server:app --host 0.0.0.0 --port 5001 --workers \"${PII_WORKERS:-1}\""]