Playground Container Registry

What is registry.iximiuz.com

Every playground run comes with its own private container registry, reachable from all of the playground's VMs at registry.iximiuz.com. It's a stock CNCF Distribution registry - the same registry image you would run yourself - started together with the playground and torn down with it. No sign-up, no configuration, no rate limits - just push and pull.

A few things the registry is good for:

  • Practicing the image publishing workflow - build, tag, push, and pull on another machine - without a Docker Hub or GHCR account and without leaking your experiments to a public registry.
  • Multi-machine workflows - build an image on one VM and run it on the other VMs of the same playground, for instance, deploy it to a Kubernetes cluster whose nodes pull from the registry.
  • Learning how registries work - it's a real OCI Distribution registry, so you can poke at its /v2/ API with curl, inspect manifests and blobs, or even push an image by hand.
  • Practicing private-registry flows - docker login, credential management, authenticated pulls: custom playgrounds and challenges can put the registry behind a username and password.
  • Testing registry-aware tools - crane, regctl, skopeo, oras, docker buildx imagetools, etc. against a registry you fully control.

Quick start

Start any playground that has a container engine in it (e.g., Docker) and run:

docker pull ghcr.io/iximiuz/labs/alpine:3
docker tag ghcr.io/iximiuz/labs/alpine:3 registry.iximiuz.com/demo/alpine:v1
docker push registry.iximiuz.com/demo/alpine:v1

The image is now in the playground's registry:

curl https://registry.iximiuz.com/v2/_catalog
{"repositories":["demo/alpine"]}

...and can be pulled from any machine of the playground:

docker pull registry.iximiuz.com/demo/alpine:v1

Key facts

PropertyValue
Addresshttps://registry.iximiuz.com (port 443); the name resolves to a playground-internal address.
TLSA valid, publicly trusted certificate - no insecure-registries setting, no custom CA, plain https:// works out of the box.
AuthAnonymous read/write by default; custom playgrounds and challenges may require a docker login (see Authentication).
ScopeOne registry per playground run, shared by all VMs of that playground.
ReachabilityFrom inside the playground only (see Reachability).
LifetimeStarts empty with every playground (re)start; contents are dropped when the playground is stopped or destroyed.
ImplementationStock CNCF Distribution (registry:3) - no web UI, no pull-through cache, no per-user namespaces.

Pushing and pulling images

Because the registry has a proper TLS certificate and a DNS name that resolves in every playground VM, any registry client works with it out of the box - no daemon flags, no trust store tweaks. Just prefix the image name with registry.iximiuz.com/.

Example:

docker tag myapp:dev registry.iximiuz.com/myapp:dev
docker push registry.iximiuz.com/myapp:dev

If the playground's registry is protected with credentials, you will need to sign in first with:

docker login -u USERNAME registry.iximiuz.com

Registry CLIs: crane, regctl, skopeo

Copying images between registries without a container engine is often the fastest way to populate the playground registry. The Docker and Kubernetes playgrounds ship with crane and regctl preinstalled:

crane copy ghcr.io/iximiuz/labs/nginx:alpine registry.iximiuz.com/demo/nginx:alpine
crane ls registry.iximiuz.com/demo/nginx
regctl image copy ghcr.io/iximiuz/labs/busybox:latest registry.iximiuz.com/demo/busybox:latest
regctl tag ls registry.iximiuz.com/demo/busybox
regctl manifest get registry.iximiuz.com/demo/busybox:latest

Kubernetes

Kubelets on the playground's nodes pull from registry.iximiuz.com like from any other public registry - no containerd registry configuration needed. A typical "build here, run there" loop in a Kubernetes playground looks like this:

dev-machine
docker build -t registry.iximiuz.com/demo/web:v1 --push .
dev-machine
kubectl create deployment web --image registry.iximiuz.com/demo/web:v1
kubectl rollout status deployment web

If the playground's registry is protected with credentials, create a pull secret and reference it from the Pod spec (or the default service account):

kubectl create secret docker-registry regcred \
  --docker-server=registry.iximiuz.com \
  --docker-username=<username> \
  --docker-password=<password>

The registry API

The registry speaks the standard OCI Distribution API, so curl is all you need to explore it:

# API version check (200 OK means the registry is up)
curl -i https://registry.iximiuz.com/v2/

# List repositories
curl https://registry.iximiuz.com/v2/_catalog

# List tags of a repository
curl https://registry.iximiuz.com/v2/demo/alpine/tags/list

Accessing the registry from your local machine

The registry lives on a playground-internal address, so your laptop's docker push registry.iximiuz.com/... won't reach it directly. Two ways around it:

  1. Push from the playground VM - the easiest option. If you build locally, set up the VM as a remote Docker context or builder and let the VM's Docker daemon do the pushing: docker buildx build --builder remote-builder --push -t registry.iximiuz.com/myapp:dev .
  2. Forward the registry port to your machine with labctl port-forward:
labctl port-forward <playground-id> -L 127.0.0.1:8443:registry.iximiuz.com:443
curl --resolve registry.iximiuz.com:8443:127.0.0.1 https://registry.iximiuz.com:8443/v2/_catalog

The certificate is still valid because the host name stays registry.iximiuz.com (the port isn't part of the certificate). For the Docker CLI, which doesn't have a --resolve flag, add 127.0.0.1 registry.iximiuz.com to your local /etc/hosts and use the registry.iximiuz.com:8443/... image names.

Additional resources

Learning materials that use the playground registry:

Authentication, reachability, and lifetime

Authentication

By default, the registry is anonymous: anyone inside the playground can push and pull without logging in. (A docker login registry.iximiuz.com with made-up credentials still "succeeds" in this mode - the registry simply ignores the credentials.)

Playground authors can put the registry behind a single username/password pair (see Configuring the Playground Registry). When that's the case, every request - pulls, pushes, and even the /v2/_catalog listing - requires HTTP Basic auth, and the usual login commands apply:

docker login registry.iximiuz.com -u <username> --password-stdin
crane auth login registry.iximiuz.com -u <username> -p <password>
regctl registry login registry.iximiuz.com -u <username> -p <password>
curl -u <username>:<password> https://registry.iximiuz.com/v2/_catalog

Where to find the credentials:

  • For challenges, tutorials, and shared playgrounds - in the task description or the machine's welcome message (if the author meant for you to know them at all).
  • For your own custom playgrounds - on the playground's settings page, under the Registry tab, or in the registryAuth field of the manifest.

Reachability

The registry is reachable from any playground VM that has a default route - i.e., at least one interface on a non-private network. This is the case for every official playground and for most custom ones. Machines attached only to private networks cannot reach the registry.

The registry is not reachable from the Internet - registry.iximiuz.com resolves to a playground-local address even on public DNS, which is meaningful only inside a playground. To use it from your laptop, see Accessing the registry from your local machine.

Lifetime and persistence

The registry storage is ephemeral - even more so than the playground VMs themselves:

  • Every playground run starts with an empty registry.
  • Stopping a playground snapshots the VM drives but not the registry: after a restart, the images you pulled into the VM's local Docker/containerd store are still there, but the registry is empty again.
  • Forked runs inherit the VM drives of the source run, not its registry contents.
  • Destroying a playground removes the registry together with everything else.

If you need certain images to be present in the registry every time a playground starts, use an init task to (re)populate it, or bake the images into a custom rootfs so they are available locally without a registry roundtrip. Both approaches are described in Configuring the Playground Registry.