Announcing ctr.run: on-demand Docker builds

Fernando Mayo
Scope
Published in
3 min readDec 4, 2019

At Undefined Labs, we’re building tools to solve challenges in software engineering so development teams can do more, faster. Being developers ourselves, we often find inspiration for new products in the problems that we face while building other solutions. This is how ctr.run (aka container-run) was born.

Why ctr.run?

We built ctr.run to stop wasting time and money building, pushing, and storing container images that never get used – think about all those images being built as part of CI on every commit “just in case”. To speed up all container builds with automatically configured caching and parallelism that works everywhere: locally, across CI providers, and container runtimes. And to eliminate the guesswork of what tag to pull to see the latest changes in master or a feature-branch.

Using ctr.run is easy, simply docker pullor docker run the git commit you need when you need it. You can try it out now with any public git repository, for example:

$ docker run ctr.run/github.com/undefinedlabs/hello-world:master

and just like that, this is what you get out of the box:

  • Automatic build caching
  • Parallel build step execution
  • CDN-based edge caching
  • Git-inherited authorization
  • On-demand builds
  • Works with Kubernetes and other container runtimes

ctr.run works as a “virtual” docker image registry, where container image repositories map to git repositories. Container image repository names are built by prepending ctr.run/ to the git repository URL, and by using a git reference (a branch, a tag, or a commit hash) as the image tag:

ctr.run/<git repository URL>[/path]:(branch|tag|commit hash)

In the example above, running:

$ docker run ctr.run/github.com/undefinedlabs/hello-world:master

will build the latest commit of the master branch of the https://github.com/undefinedlabs/hello-world repository at the time of the command execution, and then serve the resulting image.

The tag latest always points to the tip of the master branch. ctr.run will always check for updates in the git repository, but don’t worry, because it will also use the cache automatically, avoiding rebuilds if nothing changed.

If you want to build a subdirectory of your git repository, just append it to the end of the image name:

$ docker run ctr.run/github.com/docker-library/redis/5.0:master

This will build https://github.com/docker-library/redis/tree/master/5.0. Pretty straightforward, right?

Because ctr.run acts as a regular docker image registry, you can use it on any platform that runs container images, for example, in Kubernetes. Just use the ctr.run/... image name in your pod spec and that’s it!

If your git repositories are private, just log into ctr.run with your GitHub, Bitbucket or GitLab credentials, and use the provided username and password to authenticate your docker client. This way, when you pull an image using those credentials, your git credentials will be used to access the source code to be built. No need for separate authorization mechanisms.

Under the hood, ctr.run uses BuildKit, an amazing open source project that enables efficient container image builds by providing concurrent dependency resolution and automatic instruction caching. You should check it out!

Try it out RIGHT now!

ctr.run is currently available as a public and free alpha release. It works with any public GitHub, Bitbucket or GitLab repository without authentication, and if you sign up, you can also use it for private repositories. Try it out today, and never build another docker image locally ever again!

$ docker run -it ctr.run/github.com/docker/doodle/cheers2019:master

We hope ctr.run helps you and your team ship faster by removing unnecessary steps on your CI/CD pipeline. Let us know what you think!

--

--