Many developers use Docker the old-fashioned way -- a
docker build and a
docker run. Some non-obvious ways to use Docker.
As a compiler. I gave a talk at DockerCon back in 2019 about the potential to use Docker as a compiler, and the idea is finally coming to fruition. Use a multi-stage build to copy the output files to a scratch container, then use the
--output flag on
docker build to output the contents of an image build to a folder. Now you can easily cross-compile binaries (using multiple
--platform targets) or whatever else without dealing with actual Docker images. See an example.
As a task-runner alternative to
make. With Docker Buildkit, you can write alternative frontends to build images (other than the Dockerfile). Together with the built-in caching infrastructure, this makes Docker an interesting replacement for
make. That's part of the idea behind the co-founder of Docker's second act, Dagger. For a look at how it works behind the scenes, look at An Alternative to the Dockerfile.
Registries as a configuration store. Docker image registries just store tarballs and metadata, so you can use them to build an easy place to store arbitrary configuration (tarballs) in environments where you only have access to a registry endpoint.
Git repositories as docker images. I outline in Docker Merge how you might use image layers as git commits to store images in git repositories or merge filesystems.
As a cross-platform compatibility layer. Local Docker environments (like Docker Desktop or what I helped build, minikube) spend just as much time thinking about virtual machines as they do containers. That's because Linux containers are a Linux concept – yet most developers use macOS or Windows. Having a reproducible Linux environment on any machine comes in handy. And now, with the quick uptake of ARM chipsets for consumers and enterprises, it's much more likely that you're developing or deploying on a different architecture. Docker is probably the least painful way to manage that.
Building Linux Kernels. LinuxKit was an attempt to build Linux kernels like we build containers – minimal, immutable, and easier iterations.