MODULE 4  ·  DAY 1

Packaging Models as OCI Artifacts

Ship a model like a container image — versioned, layered, registry-native

Kitfile weights adapter config prompts one sealed ModelKit — pushable to any OCI registry

Gourav Shah  ·  School of DevOps & AI  ·  KitOps · ModelKit · ORAS

M4·01

What you'll learn

Why models belong in OCI registries — how to pack, push, and pull them.

12 34 Why an OCI artifact is the right home for a model — versioned & layered Author a Kitfile and pack a ModelKit with the kit CLI Push & pull across GHCR, Docker Hub, Quay, Harbor — one syntax Selective-pull just the weights; contrast KitOps with docker model
M4·02

The problem with loose model files

Weights, prompt, config scattered — every receiver re-assembles by hand.

shared drive: weights Slack link: prompts README: "also grab v3" Receiver re-assembles by hand versions drift wrong prompt + wrong weights nothing signed
M4·03

A ModelKit is a sealed, labelled crate

One signed bundle — open it and the contents match the manifest exactly.

Kitfile (manifest) model weights .gguf code LoRA adapter (M3B) config quantization prompts system prompt
M4·04

An OCI artifact is a layered blob store

The same mechanism that stores container images stores anything.

Container image base OS layer app layer config layer same spec ModelKit model weights layer code / prompts layer manifest + config SHA-256 + signed
M4·05

KitOps, ModelKit & ORAS

A CNCF stack: the format, the CLI, and the library every registry speaks.

kit CLI pack · push · unpack · ModelKit format ORAS OCI Registry As Storage — push/pull typed artifacts OCI distribution API the standard every registry speaks GHCR · Docker Hub · Quay · Harbor · Artifactory · registry:2
M4·06

The Kitfile — your shipping manifest

A tiny YAML file; each field maps to one typed OCI layer.

Kitfile manifestVersion: "1.0.0" package: {name, version, authors} model: {path: ./model/*.gguf} code: [{path: ./prompts.txt}] manifest annotation registry UI metadata model layer the weights blob code layer prompts / config
M4·07

The lifecycle: pack → push → pull → run

From a workspace to a serving node — the registry is the hub.

workspace kit pack Registry acme-docs-model:1.0.0 serving node kit unpack runtime llama.cpp push pull weights are never "run" as a container — unpacked to a directory, then loaded by a runtime
M4·08

Selective pull — grab only what you need

A warehouse shelved by chapter: pull just the box you need.

ModelKit model (weights) code (scripts) datasets --filter=model --filter=code --filter=datasets Serving node weights only — skips gigabytes CI pipeline lint the inference scripts Data-science notebook analyse data, no weights
M4·09

One artifact, every registry

Same kit push / unpack syntax — only the target reference changes.

ModelKit kit push <ref> GHCR Docker Hub Quay.io Harbor (private) Artifactory local registry:2
M4·10

ModelKit / ORAS vs docker model package

Both pack a GGUF into an OCI artifact — scope is the difference.

KitOps ModelKit docker model package CNCF · portable kit — works anywhere any OCI registry typed layers: model/code/data selective pull (--filter) Docker-specific needs Docker Desktop Docker Hub primary single model blob no selective pull
M4·11

TO THE LAB

Ship your model like an image

model code config prompts Registry Serving node

Pack SmolLM2 + prompts, push, pull on a clean dir, then selective-pull.

Next up: Lab — Pack & Push a ModelKit with KitOps  ·  Gourav Shah · School of DevOps & AI

M4·12