DEV Community

Michael Lohr
Michael Lohr

Posted on • Edited on • Originally published at blog.lohr.dev

Dev Containers: Open, Develop, Repeat...

Dev containers allow you to open up projects and have them running in a fully pre-configured environment with one click!

It is especially useful if you want to keep your system clean of different SDKs with different (conflicting) Versions (looking at you Python 👀) or work on many different projects, which require different setups. It is also helpful to provide a dev container for other people to start working on your projects because they get up and running within seconds!

I have used them for more than two years and it made my developer workflow so much easier. I nowadays use them in every project - work and private!

Intro

How it works? Dev containers is a specification based on Docker. This specification describes a metadata file (devcontainer.json), which defines how the project (Docker container, IDE settings, plugins, etc) is set up.

It can look as simple as:

{
    "name": "Rust",
    "image": "mcr.microsoft.com/devcontainers/rust:1-bullseye",
}
Enter fullscreen mode Exit fullscreen mode

Or get more complex like, this configuration which is based on a local Dockerfile, installs "dev container features" (will be explained later), configures some extensions, and my terminal:

{
    "name": "My Rust IDE",
    "build": { "dockerfile": "Dockerfile" },
    "features": {
        "ghcr.io/guiyomh/features/just:0": {}
    },
    "customizations": {
        "vscode": {
            "extensions": [
                "rust-lang.rust-analyzer",
                "tamasfe.even-better-toml",
                "serayuzgur.crates",
                "kokakiwi.vscode-just"
            ],
            "settings": {
                "terminal.integrated.defaultProfile": "zsh"
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

As you can see from the customizations section, dev containers are IDE agnostic. For example, there is a project implementing dev container support into nvim. But since the Visual Studio Code (vscode) team at Microsoft invented dev containers, it is currently the IDE with the best dev container experience.

A dev container can be bootstraped by using the vscode UI or creating the configuration file by hand. There are a bunch of pre-made dev container configurations maintained by the vscode team and community ready to be used:

Image description

This video is a good resource on how to learn the basics of dev containers and how to use them in vscode:

Dev Container Features

dev containers not only allow you to define which extensions should be installed and which configuration settings shall be set, but they also have something they call "dev container features".

They are reusable modules that contain installation scripts and dev container configurations. This means allows you to configure your development environment even quicker (and install them using a vscode UI).

Image description

In my example above, I installed the developer tool "Just" as a dev container feature. I could also install it by adding the install script to my Dockerfile. However, I would have to build my own Dockerfile and would have to maintain this piece of code myself. This dev container Feature works on different architectures and base images, which makes them convenient to use.

A list of available dev container features, can be found here. However, you can also develop your own features and publish them, like I did.

Opening dev containers From the CLI

So you can use dev containers from the vscode user interface rather intuitively. All configurations can also be edited directly and there is even a CLI. However, this CLI is made editor agnostic, so there is no vscode integration.

What I have been always missing was just a simple command to open up a dev container in my current directory, inside vscode. Turns out it is not that easy!

Now, there is a proprietary dev container CLI version included in vscode (which can be only installed by adding C:\Users\<USER>\AppData\Roaming\Code\User\globalStorage\ms-vscode-remote.remote-containers\cli-bin to the PATH), that offers a devcontainer open command. I am not sure if there is a version for Linux as well. But what I am sure of, is that it sends some kind of telemetry data to Microsoft by default.

I was not happy with this solution, so I built vscli, a vscode CLI tool to launch projects and support dev containers. It works on most platforms and is written in Rust. It includes a simple terminal UI, which allows you to quick-launch your recently opened projects:

Image description

Check it out here: https://github.com/michidk/vscli

GitHub Codespaces

dev containers also power GitHub Codespaces, which allows you to have the same dev container experience in the Browser running in the Cloud!

Image description

It is a bit like github.dev (you can replace the .com with a .dev or just press . on any GitHub repo and you will get the project editable in a vscode web version), but with all the extensions and dev container running on a machine in the Cloud.

Closing Thoughts

I recommend you to check out dev containers, it made my life so much easier. At this stage, they are also pretty mature and supported by a large community.

I even know some VIM people, using vscode from time to time just because of dev containers 😉

Top comments (0)