Sindri is read-only container registry that builds images on-demand, as they are pulled.
- You're on a platform team providing base images for application teams, but the tool versions, package registry configurations, and internal certificates that they need are moving targets.
- You want to make edge builds available to users of your project, but they would mostly go unused (e.g. nightly builds).
Generally, any time you want a container image to be available to container runtimes that cannot build images themselves (e.g. Kubernetes), but you don't want to spare the compute and storage to build and store it in case it isn't needed, Sindri can help. Read on for the specific applications that inspired me to build Sindri.
Sindri uses Dagger to build images on-demand. It can store the built images in various backends, such as in OCI registries, on disk, and in s3-compatible buckets.
Any Dagger module "sindri" that exposes a function "container" which takes two strings as arguments "name" for the <name> and "reference" for the <reference> and returns a Dagger container is supported--just run sindri from the module's directory. See interface for a minimal example, and the rest of the modules for some cool use-cases. Following is a list of example uses of Sindri's in-tree modules, plus instructions on how to use your own.
Run Sindri with the steamapps module for building containers for Steamapp dedicated servers:
docker run --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri --debugThen start pulling container images from Sindri:
docker pull --tls-verify=false localhost:5000/corekeeperRun Sindri with the wolfi module for building Wolfi containers with pre-installed packages:
docker run --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri:wolfi --debugThen start pulling container images from Sindri:
docker pull --tls-verify=false localhost:5000/go-1.25Run Sindri with the git module for building containers from Git repositories' Dockerfiles:
docker run --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri:git --debugThen start pulling container images from Sindri:
docker pull --tls-verify=false localhost:5000/github.com/frantjc/sindri/testdataRun Sindri from the directory of your module that implements Sindri's Dagger module interface:
docker run --volume `pwd`:/home/sindri/.config/sindri/module --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri --debugThen start pulling container images built by your module from Sindri:
docker pull --tls-verify=false localhost:5000/<name>:<reference>Sindri supports multiple storage backends for cacheing and serving container image manifests and blobs after they are exported from Dagger. All backends can be used via a gocloud.dev URL.
An additional query parameter is supported by Sindri for opening buckets:
use_signed_urls=true. Use this to avoid proxying container image content through Sindri for buckets that support it. This feature should reduce cost and improve performance.
Run Sindri using an s3 bucket as its storage backend:
docker run --volume ~/.aws:/home/sindri/.aws --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri --debug --backend s3://<bucket>?use_signed_urls=trueRun Sindri using a local directory as its storage backend:
docker run --volume /tmp:/tmp --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri --debug --backend file:///tmpThe same pattern follows for any other gocloud.dev/blob drivers.
Run Sindri using ghcr.io as its storage backend:
docker run --env GITHUB_TOKEN=ghp_xxx --publish 5000:5000 --detach --rm ghcr.io/frantjc/sindri --debug --backend registry://ghcr.io/<org>/<repo>ghcr.io creates new container packages as private which must be manually changed to public as of writing. This will cause the first pull of any
<name>from Sindri using ghcr.io as its storage backend to fail.
This is actually how I use Sindri personally with the steamapps module--you can see the stored images on my GitHub page.
- Nixery for the idea.
- Chainguard's registry-redirect for providing a very useful reference for implementing the registry backend.
- Dagger for being awesome.