Getting started
In this tutorial you configure peryx as a container registry, start it, pull an image through a cached proxy of Docker Hub, then build and push an image of your own to a private hosted store. It takes about ten minutes.
An OCI image is a small tree, not one file: a manifest (a JSON document listing the image's parts), a config blob,
and one or more layer blobs. Each part is a blob addressed by the sha256 of its bytes, and a mutable tag
(latest, 1.0) points at a manifest. peryx serves all of this over the container /v2/ protocol that docker,
podman, and crane speak.
Prerequisites
You need a container client (docker, podman, or crane) and a
peryx binary. Pick whichever install channel fits; installation lists them all:
# standalone binary, no toolchain involved
curl -LsSf https://github.com/tox-dev/peryx/releases/latest/download/peryx-installer.sh | sh
# needs a Rust toolchain (https://rustup.rs); rust-toolchain.toml pins the version
git clone https://github.com/tox-dev/peryx.git
cd peryx
cargo build --release
Configure peryx
Container images are content-addressed and immutable, so <name> in /v2/<name>/… carries the index route as a prefix:
an index at route dockerhub proxying Docker Hub serves library/alpine as dockerhub/library/alpine. Write a config
with two indexes: a cached proxy of Docker Hub, and a hosted store for your own images:
# peryx.toml
[[index]] # cached: read-through cache of Docker Hub
name = "dockerhub"
route = "dockerhub"
ecosystem = "oci"
cached = "https://registry-1.docker.io"
[[index]] # hosted: your own images, push needs the token
name = "images"
route = "images"
ecosystem = "oci"
hosted = true
upload_token = "demo-secret"Start peryx
Start the server with that config:
peryx serve --config peryx.toml # ./target/release/peryx serve when built from source
peryx is now listening on 127.0.0.1:4433. Leave it running and use a second terminal for the rest of the tutorial.
docker and podman trust a loopback registry (localhost, 127.0.0.0/8) over plain HTTP with no configuration,
so on the same host the commands below work as written. Reaching peryx over the network (or from Docker Desktop, whose
engine runs in a VM) needs either TLS (the production path, no client flag) or the
client's insecure-registry setting. crane and podman take a per-command flag; the snippets show it.
Pull through the cache
Pull library/alpine through the dockerhub route. The first pull runs Docker Hub's bearer-token handshake, verifies
each blob against its digest, and caches it; later pulls come from disk:
docker pull 127.0.0.1:4433/dockerhub/library/alpine:latest
podman pull --tls-verify=false 127.0.0.1:4433/dockerhub/library/alpine:latest
crane pull --insecure 127.0.0.1:4433/dockerhub/library/alpine:latest alpine.tar
Push your own image
Pushing needs the hosted index's upload_token. peryx accepts any username; the token is the Basic-auth password. Log
in, tag an image for the images route, and push it. Blobs stream into the content-addressed store and are verified on
commit:
docker login 127.0.0.1:4433 -u _ -p demo-secret
docker tag alpine 127.0.0.1:4433/images/app:1.0
docker push 127.0.0.1:4433/images/app:1.0
podman login --tls-verify=false 127.0.0.1:4433 -u _ -p demo-secret
podman tag alpine 127.0.0.1:4433/images/app:1.0
podman push --tls-verify=false 127.0.0.1:4433/images/app:1.0
crane auth login 127.0.0.1:4433 -u _ -p demo-secret
crane push --insecure alpine.tar 127.0.0.1:4433/images/app:1.0
Verify
Pull your image back from a clean state to confirm it round-trips. Ask the registry for the tags it holds, then pull:
curl -s http://127.0.0.1:4433/v2/images/app/tags/list # {"name":"images/app","tags":["1.0"]}
docker pull 127.0.0.1:4433/images/app:1.0
peryx also serves a web interface on the same port. Open http://127.0.0.1:4433/ for a live
dashboard of the configured indexes and their request counters; the same numbers are
Prometheus metrics at /metrics.
Reclaim deleted blobs
peryx removes one repository link for OCI blob deletion and leaves the payload in its shared content store because another repository or ecosystem may reference the same digest. After you delete the image, inspect unreferenced bytes before removing them:
peryx cache purge orphaned-blobs
peryx cache purge orphaned-blobs --yes
The first command prints a dry-run plan. The second unlinks blobs that no installed ecosystem references.
Where next
- Pull a Docker Hub official image: pull
ubuntuthrough the cache by its short name, the way you would against Docker Hub. - Run a container registry: add a virtual index so your hosted images shadow upstream, and delete images you no longer want.
- OCI performance: how peryx compares to distribution and zot as a Docker Hub cache.
- Configuration reference: every TOML key, including TLS so clients need no insecure flag.