Written by Ayooluwa Isaiah ✏️
As one of the most widely used container platforms, Docker, a monolithic tool, handles every aspect of the containerization process, from building, running, and inspecting container images.
In August 2021, Docker Desktop announced changes to its licensing, meaning it will no longer be free for companies with more than 250 employees or over $10 million in revenue. However, there are several alternative approaches to containerization, often in the form of standalone tools, which in some cases offer a better result than what Docker delivers.
In this article, we’ll cover a few Docker alternatives that act as drop-in replacements for various aspects of the Docker ecosystem. Each tool covered in this tutorial adheres to the Open Containers Initiative (OCI) specification, which includes specifications for container runtime, container distribution, and container images. Let’s get started!
1. Podman
Podman, a container engine developed by RedHat, is one of the most prominent alternatives to Docker for building, running, and storing container images. Podman maintains compatibility with the OCI container image spec just like Docker, meaning Podman can run container images produced by Docker and vice versa.
Podman's command line interface is identical to Docker's, including the arguments. You can simply alias the docker
command to podman
without noticing the difference, making it easy for existing Docker users to transition to Podman:
# .bashrc
alias docker=podman
Unlike Docker, which uses the dockerd
daemon to manage all the containers under its control, Podman is daemonless. Therefore, there's no persistent connection to some long-living process, removing the single point of failure problem in Docker, where an abrupt crash in the daemon process can kill running containers or cause them to become orphaned.
Podman interacts with the image registry, storage, and Linux kernel, and its containers are independent of any central process. Instead, the containers are started as child processes of the Podman process, heavily utilizing user namespaces and network namespaces.
Podman also differentiates itself from Docker by utilizing rootless containers by default. Root access is not necessary for launching and operating a container, but it helps to mitigate potential vulnerabilities in the container runtime that can cause privilege escalation.
Note that Docker now supports a rootless mode, which debuted as an experimental feature in Docker Engine v19.03 before being stabilized in v20.10. However, its use is not yet widespread in the ecosystem.
An additional feature of Podman that is not yet present in Docker is the ability to create and run pods. A pod is a collection of one or more containers that utilize a shared pool of resources and work closely together to achieve a specific function. Pods are also the smallest execution unit in Kubernetes, making the transition to Kubernetes easier should the need arise.
2. Buildah
Buildah is an alternative to Docker for building images. Also developed by RedHat, Buildah is often used together with Podman. In fact, Podman uses a subset of Buildah's functionality to implement its build
subcommand.
If you need fine-grained control over images, you should use the full Buildah CLI tool. At the time of writing, Buildah works on several Linux distributions but is not supported on Windows or macOS.
The images that Buildah produces are fully compliant with the OCI specification, operating in the same manner as images built with Docker. Buildah can also create images using an existing Dockerfile
or Containerfile
, making migration much easier. Buildah also allows you to use Bash scripts that sidestep the limitations of Dockerfiles, automating the process more easily.
Like Podman, Buildah follows a fork-exec model that doesn’t require a central daemon or root access to operate.
One advantage of using Buildah over Docker is its ability to commit many changes to a single layer, which is a long-requested feature among container users. Buildah also provides the ability to create an empty container image storing only metadata, making it easy to add only the necessary packages that are required in the image. In turn, the final output is smaller than its Docker equivalent.
Another difference is that Buildah images are user-specific, so only the images built by a user will be visible to them.
3. Buildkit
Buildkit is a new image building engine for Docker developed as part of the Moby project. From Docker ≥v18.09, Buildkit is integrated into docker build
, but it also comes as a standalone tool.
One of Buildkit’s headline features includes improved performance through parallel processing of image layers that don’t depend on each other. Another is better caching, which reduces the need to rebuild each layer of an image. Finally, Buildkit offers extensibility through a more pluggable architecture. Buildkit also introduces rootless builds and the ability to skip unused stages.
At the time of writing, Buildkit is available on an opt-in basis. To enable Buildkit before building an image, you must use the DOCKER_BUILDKIT
environmental variable in your shell:
$ DOCKER_BUILDKIT=1 docker build .
You can also configure Docker to use Buildkit by default. Simply edit or create the /etc/docker/daemon.json
file as follows:
{
"features": {
"buildkit": true
}
}
After saving the file, reload the daemon to apply the change:
$ systemctl reload docker
It's easy to tell when Buildkit is being used due to its output, which differs from the default engine:
$ DOCKER_BUILDKIT=1 docker build . [+] Building 30.8s (7/7) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 142B 0.1s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.6s => [auth] library/centos:pull token for registry-1.docker.io 0.0s => [1/2] FROM docker.io/library/centos:latest@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6 14.3s => => resolve docker.io/library/centos:latest@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c 0.0s => => sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 762B / 762B 0.0s => => sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc 529B / 529B 0.0s => => sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6 2.14kB / 2.14kB 0.0s => => sha256:a1d0c75327776413fa0db9ed3adcdbadedc95a662eb1d360dad82bb913f8a1d1 83.52MB / 83.52MB 2.0s => => extracting sha256:a1d0c75327776413fa0db9ed3adcdbadedc95a662eb1d360dad82bb913f8a1d1 10.8s => [2/2] RUN yum -y install httpd 14.7s => exporting to image 1.0s => => exporting layers 1.0s => => writing image sha256:c18170a407ca85218ee83526075a3f2a2e74f27d7bd5908ad68ba2328b4f4783 0.0s
4. Kaniko
Developed by Google, Kaniko is used to develop container images inside of a container or a Kubernetes cluster. Like Buildah, Kaniko does not require a daemon, and it can build images from Dockerfiles without depending on Docker.
The major difference between Docker and Kaniko is that Kaniko is more focused on Kubernetes workflows, and it is meant to be run as an image, making it inconvenient for local development.
5. Skopeo
Skopeo is yet another tool developed by RedHat for various operations on container images and image repositories. Skopeo can be used as an accompanying tool for Podman and Buildah, which are both intended to inspect images, transfer them from one registry to another, and bulk delete them if necessary.
Skopeo provides an inspect
subcommand, which provides similar low-level information about a container image to docker inspect
.
In contrast to Docker, Skopeo can help you gather useful information about a repository or a tag without having to download it first:
$ skopeo inspect docker://docker.io/fedora # inspect remote image
{
"Name": "docker.io/library/fedora",
"Digest": "sha256:72c6c48a902baff1ab9948558556ef59e3429c65697287791be3c709738955b3",
"RepoTags": [
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"26-modular",
"27",
"28",
"29",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"branched",
"heisenbug",
"latest",
"modular",
"rawhide"
],
"Created": "2021-11-02T21:29:22.547065293Z",
"DockerVersion": "20.10.7",
"Labels": {
"maintainer": "Clement Verna \u003ccverna@fedoraproject.org\u003e"
},
"Architecture": "amd64",
"Os": "linux",
"Layers": [
"sha256:fc811dadee2400b171b0e1eed1d973c4aa9459c6f81c77ce11c014a6104ae005"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"DISTTAG=f35container",
"FGC=f35",
"FBR=f35"
]
}
You can use skopeo copy
to copy a container image from one remote registry to either another remote registry or a local directory. Anotther related feature is Skopeo's ability to synchronize images between container registries and local directories with the skopeo sync
command.
6. Dive
Dive is a tool for inspecting, analyzing, and optimizing container images. Dive can show image contents by layer, highlighting the differences between each. Dive can also analyze your image, providing a percentage score for efficiency by estimating wasted space, which is helpful when you’re trying to reduce your image size.
Another useful feature is Dive’s CI integration, which provides a pass or fail result based on the image's efficiency and amount of wasted space. To access the CI integration feature, set the CI
environmental variable to true
when invoking any valid dive
command:
$ CI=true dive node:alpine
7. runc and crun
runc is a CLI tool that spawns and runs containers on Linux according to the OCI specification. runc was formerly embedded into Docker as a module but was later spun into a standalone tool in 2015.
runc remains the default container runtime in Docker, Podman, and most other container engines. An alternative to runc is crun, which was developed by RedHat and written in C instead of Go like most Linux container tools.
crun boasts better performance and lower memory usage compared to runc, as well as the ability to set stricter limits on the memory allowed in the container. crun is also OCI-compliant and feature-compatible with runc, so you can use it as a replacement for runc in Docker, Podman,containerd
, and any other container engine that uses OCI-compliant container runtimes. See the introductory article on crun for a more detailed comparison to runc.
Wrapping up
In this article, we've described several alternatives to Docker for building, running, and distributing container images. Although Docker remains the dominant platform for containerization and container management, it's good to know about alternative tools that may work better for your use case.
Replacing a specific Docker aspect should be fairly seamless because each tool mentioned adheres to the OCI specification. Be sure to leave a comment if there is any tool you think we missed. Thanks for reading!
LogRocket: Full visibility into your web apps
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
Top comments (0)