Deployment
How indx ships: one image that carries the API, every engine, the weights and the site, and the targets it runs on.
indx ships as one image. It carries the API, every engine extra but s3, the weights
those engines download, and the documentation site, all served from one origin by examples/app2.py
(ADR-0039).
The image is the unit of deployment; a target runs it and puts a perimeter in front of it.
The image
Section titled “The image”Dockerfile builds linux/amd64 only (vibrato has no aarch64 wheel), in stages ordered so a
change invalidates only what depends on it: manifests, third-party wheels, the packages; the
weights and the site are each built in a stage of their own and copied in last.
The weights are an image of their own
(ADR-0041).
The weights target is the one stage that reaches Hugging Face: scripts/warm_weights.py
constructs each engine there and the three caches it fills are the whole image. Its tag is
w-<key>, where scripts/weights_key.sh digests the five files that name a model, and both
workflows publish it to GHCR only when that tag is absent. Every later build, in CI and in the
deploy, pulls the weights from GHCR instead. The runtime stage then reruns the warm script with
the network off, so a build fails when the published weights are not complete for its code.
| Command | What it does |
|---|---|
just infra::image::weights |
Build indx-everything-weights:local from Hugging Face, once |
just infra::image::build |
Build indx-everything:local on top of it |
just infra::image::run |
Run it on :8000 |
just infra::image::verify |
Prove an already built image: /health, every capability the extras add, the site, Scalar |
just infra::image::smoke |
build then verify |
.github/workflows/image.yml runs verify on every change to the image’s inputs. A deploy
workflow builds the same Dockerfile into its registry, tagged sha-<commit>, and shares one
layer cache with it.
Targets
Section titled “Targets”- AWS: one Fargate task behind an ALB that admits only Cloudflare’s edge, three Terraform stacks, one dispatch-only workflow. The production deployment.
- Azure: one Container App on a Consumption environment serving its hostname directly on a managed certificate, one Terraform stack, one dispatch-only workflow.
- GCP: one Cloud Run service closed behind a global load balancer that is the public origin, one Terraform stack, one dispatch-only workflow.
AWS is the production deployment. Azure and GCP are one stack each, the same image, and the model
lanes as variables
(ADR-0053).
Neither has a perimeter: their hostnames are DNS-only records the operator creates by hand, the
platform issues each certificate, and a foreign Host is closed by host-based routing on Azure and
by the closed run.app URL on GCP
(ADR-0064,
ADR-0065).
Each has a dispatch-only workflow of its own, shaped like the AWS one and sharing nothing with it by
name: its own variables, secrets and GitHub Environments, so no workflow can take another cloud’s
hostname
(ADR-0054).
An operator can still apply either stack by hand; it is the same stack.