Although I am not a software developer, every now and then I tinker with software. When I do so, I tend to end up with a whole bunch of software, modules and add-ons that need to be installed before I can start to do what I want to do. After a while, my computer is a big mess and the next thing I try is impacted by whatever I did some time ago and forgot about.
There must be better ways of doing this right? Yes, there are better options and I have tried a few of them over time. The latest and greatest option: DevContainers. Let me introduce you to what I did and learned recently.
I am running virtual servers on a VMware ESXi computer and I love(d) it. This is a great way to host multiple computers on a single box. However, in the end, you end up with yet another set of (virtual) computers. Meaning: installing and configuring operating systems and all the software that needs to be installed on top of that. And once a virtual computer is running, it requires regular updating, patching and fixing. It’s not a problem for long running systems, but this is not a great way to just try something out on a rainy afternoon.
So, what about using a (Docker) container instead of a VM? That’s exactly what some engineers must have thought and some years ago this resulted in something called: development containers.
Containerization is not new and is used already for a lot of things, but to use it for development purposes was new at that point in time. Instead of setting up a VM, you define a container which holds all the bells and whistles needed to build, test and run code that is being developed. Using different containers, you can keep things separated, clear and focused on the task at hand.
Nowadays, the toolset to use dev containers is great and there are more and more providers that offer services related to it as well. But I do not want to use such a service. I want to test something here and now on my computer, without messing things up and spending hours on installing software and add-ons. No problem, we can do all of this on a Windows laptop and by following some best practices, make sure that in time it can be moved up to such a service providers solution if needed.
Mention container and almost every developer translates it into “Docker container”. Yes, Docker is a company and a set of products that put containerization on the map, but not every container requires Docker; luckily.
In August 2021, Docker changed its licensing terms. Meaning, if you are working for a company of a certain size (in terms of number of employees or annual revenue), you can’t use (some of?) their free products anymore. Even when I use my company laptop for personal development work, I can’t use the Docker products without a paid subscription.
I mentioned “some of?”, since it looks like (hey, I am not a lawyer…) this only applies to Docker Desktop and not to Docker Engine for example. However, it is not clear enough for me as end user and all their products integrate or depend on each other in some way or form. This makes it too difficult to understand what I am (not) allowed to do. Therefore, I won’t take the risk and consider these licensing terms to apply to everything Docker delivers.
I understand why Docker went for this approach, but I am not willing to go for a paid subscription for the number of times I use their software. Even when the subscription fee is low, this still doesn’t add up. Time to find alternatives.
Podman is a free, open-source tool to find, run, build, share and deploy applications using Open Containers Initiative (OCI) Containers and Container Images. The podman command line interface is compatible with the docker CLI. Any document that mentions
docker whatever can be replaced by
Podman doesn’t run containers itself; it allows you to “make them run” somewhere. You need a runtime environment for that purpose. I have Microsoft Windows 11 on my laptop and installing podman on it, results in installing a Linux VM that runs the containers. The
podman CLI on Windows is forwarding the commands to podman running in the VM where they are executed. It took me some time to grasp that idea, but I also saw major benefits from this approach (more on that in one of the next posts).
To host a Linux VM on Windows, podman uses WSL. The current version is WSL 2 which has had many improvements on the initial version that got released in Windows 10. Setting up a Linux distribution is taking hardly any effort anymore. It’s nothing like hosting a VM on VMware ESXi or Microsoft Hyper-V.
We now have all the ingredients: a Linux VM that can run containers, a CLI/API that allows us to find, run and build these containers; and all of that on a Windows 11 laptop. But that wasn’t the goal. The goal was to have an easy way to build, test and run software (including all its dependencies) without messing up the laptop.
This is where Visual Studio Code and the Visual Studio Code Dev Containers extension comes into play. By installing some extensions in vscode and making sure that their configuration is modified to use podman instead of docker, we can do what we were aiming at.
Development containers are configured by adding a
devcontainer.json file to your project. This file details the container where the build, test and running of your software should happen.
It took me some time to get all the components in place and nicely work together. In the end, everything now does what I want it to do. I can now have one or more Linux VMs on my laptop to try things out. Next to that, I can have dev containers for specific projects without having to install a whole bunch of tools, runtimes and add-ons on my Windows laptop anymore. And all this, with just a few configuration and batch files.
There’s way too much detail to document everything in a single post. I will add a few more posts over the next few days to show the individual steps.