Pushing models & images
Pushing always requires a namespace. The hippius-hub CLI provisions one, and the docker credentials you'll need, in a single command.
Namespaces
Every artifact lives at <namespace>/<repo>:<tag>. New namespaces are public by default: anyone can pull, only you can push. Publicity is per namespace, not per repository. Pricing tiers gate storage quota and a monthly pull allowance; see hippius.com/hippius-hub and the Hub console page for the plans.
Provision a namespace
Run these three commands in order, the first time only:
hippius-hub registry plans # see pricing tiers
hippius-hub registry check my-models # is the name free?
hippius-hub registry provision my-models --docker-login
provision --docker-login does three things in one shot: creates your namespace, mints docker credentials, and runs docker login registry.hippius.com for you (skipped with a message if docker is not on PATH). The CLI's own upload / download commands also start working immediately because the credentials are cached at ~/.cache/hippius/hub/token.
If the server answers that provisioning started in the background, the secret is not printed yet. Run hippius-hub registry status until it is ready.
The Free plan refuses namespace creation until the account holds a balance of at least $10. Top up on Billing first if the balance is zero.
The robot secret prints once at the bottom of registry provision. If you lose it, rotate with hippius-hub registry rotate-token: it issues a new secret and updates the local cache.
Push
- Python (huggingface_hub)
- CLI (hippius-hub)
- Docker
- ORAS
from hippius_hub import upload_folder
upload_folder(
folder_path="./outputs/checkpoint-1000",
repo_id="my-models/qwen-7b",
revision="v1",
allow_patterns=["*.safetensors", "*.json"],
delete_patterns="*.tmp", # prune any *.tmp from the existing revision
commit_message="Initial checkpoint",
)
Drop-in for upload_folder. Re-running it merges into the existing manifest at that revision: individual files get added or replaced without wiping the rest.
Parallel upload_file calls to the same repo and revision are guarded. The first writer wins; the others raise ConcurrentManifestUpdateError and can retry. A transient failure on a single-object upload resumes from the committed offset (at most one chunk is re-sent).
For a single file, use upload_file(path_or_fileobj, path_in_repo, repo_id, revision).
# Upload an entire folder as :v1
hippius-hub upload my-models/qwen-7b ./qwen-7b --revision v1
# Add or replace a single file in an existing revision
hippius-hub upload my-models/qwen-7b ./README.md --revision v1
# Skip --revision to push to the default :main tag
hippius-hub upload my-models/qwen-7b ./qwen-7b
Folder uploads merge into the existing manifest: re-running adds or replaces individual files without wiping the rest. The indexer picks up format / architecture / parameter count / quantization within a few seconds of the push completing.
docker tag my-app:latest registry.hippius.com/my-models/my-app:v1
docker push registry.hippius.com/my-models/my-app:v1
The first push to a namespace fails if you haven't provisioned it. Subsequent pushes to repos in the same namespace work without further setup.
oras push registry.hippius.com/my-models/my-artifact:v1 \
./weights.safetensors ./config.json
oras pushes arbitrary files as OCI artifacts. Small model files (under 256 MiB) are plain OCI blobs you can also fetch with oras. Files of 256 MiB and above are stored chunked (content-defined chunks packed into content-addressed packs plus one pointer record). Read those with hippius-hub download or the Python client, which reassemble them. oras pull of a chunked repo returns packs and a pointer, not the original file. Readers must be hippius_hub 0.6.0 or newer.
Mirror a Hugging Face model
The fastest way to put an existing Hugging Face model behind your own namespace: pull with hf, push with hippius-hub:
# 1. Grab the model from HF
pip install -U "huggingface_hub[cli]" hf_transfer
HF_HUB_ENABLE_HF_TRANSFER=1 hf download Qwen/Qwen2.5-7B-Instruct --local-dir ./qwen-7b
# 2. Push the whole folder under your namespace as :v1
hippius-hub upload my-models/qwen-7b ./qwen-7b --revision v1
# 3. Confirm it landed and got indexed
hippius-hub registry repos
hippius-hub models show my-models/qwen-7b v1
The hf download CLI handles the HF side; hippius-hub upload chunks and parallelizes the push to your namespace. The copy is published on your namespace, public or private.
Script
mirror-hf.sh copies one Hugging Face model into your namespace.
sh mirror-hf.sh Qwen/Qwen2.5-7B-Instruct my-models/qwen-7b v1
The last argument is the revision. Leave it out to use main.
Load the copy by changing the import and the repo id:
from hippius_hub import snapshot_download # was: from huggingface_hub import snapshot_download
local_dir = snapshot_download("my-models/qwen-7b", revision="v1")
On Hippius, visibility belongs to the namespace. The namespace is public or private. Every repo in it shares that setting. Anyone can pull a public namespace. Only you and the keys you issue can pull a private one. Changing the namespace changes every repo already in it.
You can run the copy in other ways. mirror-hf-account.sh copies the models on your Hugging Face account into one namespace. mirror-hf-namespaces.sh puts public models in one namespace and private models in another.
hf auth login
sh mirror-hf-account.sh my-models private
sh mirror-hf-namespaces.sh --public my-models --private my-models-private
Datasets, Spaces, and buckets are skipped. When the account has both public and private models, name the group. The other models stay on Hugging Face.
Public vs private
hippius-hub registry publicity public # anyone can pull
hippius-hub registry publicity private # only your credentials can pull
Toggling publicity also resizes your quota to the plan's public or private tier.
Private namespaces: only you and the keys you issue can pull from them. Publicity is per namespace, not per repository. Issue a scoped key with hippius-hub registry keys create for CI or a teammate.
Rotate credentials
hippius-hub registry rotate-token --docker-login
Issues a new docker secret and writes it to the local cache. The old secret stops working immediately, which matters for CI pipelines that hold a copy. Re-distribute before rotating. For CI, prefer a scoped key (hippius-hub registry keys create … --role push) over the namespace robot secret.
Troubleshooting docker push 500
If docker push loops with 500 Cannot find server., check docker info | grep -i proxy. A daemon-level proxy (e.g. http.docker.internal:3128) in Docker Desktop routes the push through an unreachable proxy and the registry is never hit.
Fix: Docker Desktop → Settings → Resources → Proxies → disable it or bypass registry.hippius.com, then restart Docker Desktop. NO_PROXY in your shell does not help: the daemon ignores it.
Inference Endpoints, Spaces, Webhooks, Collections, and Discussions raise NotImplementedError. They have no OCI equivalent. HF git refs such as refs/pr/3 are not supported (use a tag as revision=). Fields pipeline_tag, library_name, tags, downloads, and likes return None.
Where to next
- Pull: download from Python, CLI, or
docker pull. - CLI reference: every
hippius-hubcommand, grouped by goal.