Deploy a model with bairav model deploy
One command, three targets. Pick the one that matches what you have on your machine.
bairav model deploy <hf-repo> # → docker compose (default)
bairav model deploy <hf-repo> --target k8s # → active kubeconfig context
bairav model serve <hf-repo> # → bare process on this host
All three run the same bairav/serving:laptop image (the bare-process target runs llama-server directly), expose an OpenAI-compatible endpoint, and persist downloaded GGUFs in ~/.bairav/models/ so subsequent runs skip the pull.
Example we’ll use throughout: Qwen/Qwen2.5-0.5B-Instruct-GGUF (~400 MB, runs on any laptop).
Not sure which model? bairav model discover
New open-weight models land every week, and most never reach the news. discover lists the top 10 on Hugging Face right now. It only shows first-party releases: fine-tunes, re-uploads and “uncensored” variants are filtered out, and each model family appears once. Each row says whether bairav can run the model today.
bin/bairav model discover # trending text models
bin/bairav model discover --sort new # newest first
bin/bairav model discover --task embedding # text | vision | embedding | image | speech
bin/bairav model discover --all # raw HF ranking, unfiltered
# MODEL RELEASED SIZE LICENSE LIKES RUN WITH BAIRAV
1 poolside/Laguna-S-2.1 82d ago ? openmdw-1.1 689 ✓ unsloth/Laguna-S-2.1-GGUF
2 Aleph-Alpha/Kolibri-1 1d ago 78B (~43 GiB Q4) apache-2.0 178 no GGUF yet
...
How to read the columns:
- SIZE is the parameter count. The
~Q4figure is roughly the 4-bit download, which is also about the RAM the model needs. - RUN WITH BAIRAV shows the most-downloaded GGUF build. The model’s own org wins first, then well-known quantizers.
- “no GGUF yet” means only safetensors/vLLM weights exist so far. Community GGUF builds usually follow within days.
Coding / reasoning / image specialisations come later as a curated layer.
What’s running? bairav model status
bairav model list is the download cache. status shows deployments on every target (local, docker and k8s): the model each one really serves, any upgrade in flight, and AGE.
NAME TARGET NAMESPACE SERVING PHASE UPGRADE AGE
qwen docker - Qwen/Qwen2.5-0.5B-Instruct-GGUF Ready - 3h
support-model k8s team-a Qwen/Qwen2.5-1.5B-Instruct-GGUF Ready from Qwen2.5-0.5B-… 12m ago 2d
bin/bairav model status support-model shows the details for one deployment:
- serving vs wanted model
- previous model and the exact rollback command
- strategy, endpoint and conditions
To swap models safely, see quickstart-model-upgrade.md.
Path 1: Docker Compose (the default, no cluster)
Ports are published on 127.0.0.1 only, so your model isn’t reachable from the network you’re on. Set BAIRAV_PUBLISH_ADDR=0.0.0.0 before deploying if you do want LAN access.
Best when you have Docker Desktop / Colima and don’t want to bring up Kubernetes.
Prerequisites: docker (with the v2 compose plugin — comes with Docker Desktop).
make image-serving # build bairav/serving:laptop (one-time)
bin/bairav model deploy Qwen/Qwen2.5-0.5B-Instruct-GGUF
bin/bairav ps
What you’ll see:
Target: docker (compose)
Name: qwen2-5-0-5b-instruct-gguf
Repo: Qwen/Qwen2.5-0.5B-Instruct-GGUF
Endpoint: http://127.0.0.1:8080/v1
StackDir: ~/.bairav/compose/qwen2-5-0-5b-instruct-gguf
…
✓ Stack up. First boot pulls the GGUF inside the container — give it a minute.
The compose file lands at ~/.bairav/compose/<name>/docker-compose.yaml. The container bind-mounts ~/.bairav/models/ to /models, so once the GGUF is pulled it persists across down → up.
Talk to it:
bin/bairav chat --endpoint http://127.0.0.1:8080/v1
# or curl directly
curl http://127.0.0.1:8080/v1/models
Tear it down:
bin/bairav model undeploy qwen2-5-0-5b-instruct-gguf
Path 2: Kubernetes (k3d on the laptop, or any real cluster)
Best when you want to exercise the full operator + Model CR path, or when you’re testing what the user’s cluster will see.
Prerequisites: docker, k3d, kubectl.
One command bootstraps everything:
make dev # = make dev-k8s
make dev is idempotent and does the full onboarding:
- Creates the
bairavsk3d cluster if it doesn’t already exist. - Builds + imports
bairav/serving:laptopandbairav/operator:laptopinto k3d (no registry needed). - Installs the
ModelCRD, RBAC, and the operator Deployment. - Waits up to 120 s for the operator to report
Available. - Tails the operator logs (Ctrl-C stops the tail; the operator keeps running).
Then, from another terminal:
bin/bairav model deploy Qwen/Qwen2.5-0.5B-Instruct-GGUF --target k8s
bin/bairav ps
What you’ll see in ps:
KUBERNETES (context: k3d-bairavs)
NAMESPACE NAME REPO PHASE ENDPOINT
default qwen2-5-0-5b-instruct-gguf Qwen/Qwen2.5-0.5B-Instruct-GGUF Loading http://qwen2-5-0-5b-instruct-gguf.default.svc.cluster.local:8080/v1
The phase moves Pending → Pulling → Loading → Ready as the operator reconciles the pod. --wait (default true) polls until Ready; pass --wait=false to return immediately.
Talk to it from inside the cluster (the in-cluster DNS name above), or kubectl port-forward to reach it from the laptop:
kubectl port-forward svc/qwen2-5-0-5b-instruct-gguf 8080:8080
bin/bairav chat --endpoint http://127.0.0.1:8080/v1
Tear it down:
bin/bairav model undeploy qwen2-5-0-5b-instruct-gguf --target k8s
# or destroy the cluster entirely:
make dev-down
Path 3: Bare process (bairav model serve)
Best for the fastest iteration loop — no container, no cluster, talk straight to llama-server. Useful when you’re debugging the CLI or the OpenAI shim itself.
Prerequisites: llama-server on your PATH (we don’t bundle it for this path — the container image is what handles the install for the other two).
bin/bairav model pull Qwen/Qwen2.5-0.5B-Instruct-GGUF
bin/bairav model serve Qwen/Qwen2.5-0.5B-Instruct-GGUF
bin/bairav ps # LOCAL section shows it
bin/bairav chat # auto-detects the running endpoint
State lives at ~/.bairav/run/port-<N>.json; ps prunes stale entries on every invocation.
Which target should I use?
| Situation | Target |
|---|---|
| “I just want to talk to an LLM on my laptop” | docker (default) |
| “I’m validating the operator / CRD behaviour” | k8s |
| “I’m debugging the BAIRAVS CLI itself” | serve (bare process) |
| “I’m going to ship this to a real cluster” | k8s (same code path as production) |
The docker and k8s targets run the same bairav/serving:laptop image with the same BAIRAV_REPO / BAIRAV_PORT / BAIRAV_FILE / BAIRAV_CTX_SIZE env contract. A model that works on docker will work on k8s and vice versa.
Cross-references
quickstart-k8s.md— deeper dive on the k3d path (cluster internals, operator install steps).ARCHITECTURE.md— why the Backend interface exists and how vLLM/Ollama plug in later.