All-in-one container
Engine and all three decode sidecars in one image. The smallest footprint and the fastest start — bring your own MongoDB.
Self-hosting Mildport keeps every customer file inside your own network. The engine verifies its license offline and has no telemetry, so it runs perfectly well in a VPC with tight egress rules — or none at all.
You bring the database and object storage. We bring the import engine and the decode sidecars.
A paid plan. Self-hosting comes with paid plans; the free tier is the cloud trial.
Image access. Our images are private. Request access once from the Self-hosting page in your account — see Image access.
A license key and the public key. Both come from your account: the key from
Licenses, the IMPORT_LICENSE_PUBLIC_KEY value from Self-hosting.
All-in-one container
Engine and all three decode sidecars in one image. The smallest footprint and the fastest start — bring your own MongoDB.
Docker Compose
The full stack as separate services: engine, database, decode sidecars, optional object storage. Good for a single host.
Kubernetes (Helm)
The engine and sidecars as a chart, each sidecar independently toggleable, with the preflight
wired into helm test.
Air-gapped
No outbound internet at all. Mirror the images, serve one frontend asset yourself, and nothing phones home. Read the runbook →
| Service | Role |
|---|---|
mildport |
The import engine and license-keyed REST API (listens on :8090) |
mongo |
Metadata, mappings, delivery log |
pdf-probe |
Decode sidecar — PDF table extraction |
xlsx-decode |
Decode sidecar — spreadsheets |
ocr |
Decode sidecar — scans and photos |
minio (optional) |
S3-compatible blob storage for large files |
Only the engine and MongoDB are required. Each decode sidecar is optional: without
pdf-probe the engine simply won’t accept PDFs, and so on. If your estate is already
Postgres, FerretDB is a verified experimental option — same
connection string, not a production database we staff yet.
The smallest possible start — one container, two environment variables:
docker login ghcr.io -u <your-github-username> # after access is granted
docker run --rm -p 8090:8090 \ -e MONGO_CONNECTION_STRING="mongodb://host:27017/cap_import" \ -e IMPORT_LICENSE_PUBLIC_KEY="<from the Self-hosting page>" \ ghcr.io/capitality-io/mildport-aioCheck it answers:
curl localhost:8090/health# {"status":"ok","service":"mildport"}That is a working engine for server-to-server calls. If a browser embeds the widget,
also set ALLOWED_ORIGINS to that page’s origin — the production image refuses every
cross-origin browser request when it is empty (including localhost). Then point the widget
at the engine with api-base-url, hand it your license key, and run a real import —
Your first import.
The chart installs straight from the OCI registry once your account has image access:
helm install mildport oci://ghcr.io/capitality-io/charts/mildport \ -n mildport --create-namespace -f values.prod.yamlhelm test mildport -n mildport # runs the preflight in-clusterBring your own MongoDB and S3-compatible storage. An all-in-one mode folds the engine and the three decode sidecars into a single pod; semantic matching stays a separate pod you can turn off. Each sidecar can also be disabled individually on the granular chart.
The engine ships a check that refuses to let you misdeploy — it validates the license setup, Mongo URI, CORS allowlist, storage, sidecar reachability and entitlements, and exits non-zero on anything blocking:
pnpm import:self-host-check # from a source checkoutdocker run --rm --env-file .env ghcr.io/capitality-io/mildport-aio \ bun dist/cli/self-host-check.js # from the imageOn Kubernetes, helm test mildport runs the same check inside the cluster, against the
config the deployment actually has.
Next: Your first import · Deployment troubleshooting · Configuration reference · Licensing