Dev Containers

Dev Containers

Docker is well-known and is widely used in the software application realm. In recent years, it has made its way into many embedded software projects. In embedded development, it is mainly used for running builds and tests locally on the machine or on Continuous Integration/Continuous Deployment (CI/CD) platforms. 

Check out our Using Docker for Embedded Development blog post to learn more about it. The Dockerfile can start off simple with a few required packages, and it quickly grows in size and complexity as a project progresses. Aside from a complicated Dockerfile, in order to develop code within a Docker container, we have to install screen-based text editors such as vim. For the developers who are not familiar with any of the screen-based text editors, they have to spend some time learning one of them before they can be productive within a Docker container. It will definitely speed things up if we can visualize and modify the files within the Docker container on an IDE. This is where Dev Containers come in.

What are Dev Containers?

A Dev Container, or Development Container, is a Docker Container that provides an isolated, consistent environment that consists of the IDE, tools, and packages that we need to develop software. Once it is set up and checked into version control, the developers can focus on the real product instead of spending extra time on setting up or replicating the build environment.

Why Dev Containers?

A dev container has all the benefits that a Docker container can offer, such as being a fast, lightweight, and standardized environment. By being able to integrate with the IDE, it provides an interface for us to interact with a Docker container and makes a complicated Docker container more manageable. The following sections will expand on the benefits of using dev containers.

Time Saving

In the beginning of a project, time spent on setting up a build and test environment is unavoidable, but we can save the time when the next developer tries to set up the same environment. When new developers join the team, many hours could be spent on trying to set up or replicate the same environment. With dev containers, one can set up the environment by just installing an IDE, such as Visual Studio Code, Docker and running the dev container.

Consistency

There are many existing ways of creating isolated environments and managing tools and packages, such as using Python Virtual Environments and Poetry, but we often still end up dealing with the “it works on my machine” situation. For example, a different version of a toolchain can result in a different binary that acts differently. By using the dev containers, all developers use the same versions of tools and configurations to build and test their code.

IDE Integration

Dev containers improve the interaction with the Docker container by integrating with the IDEs. The IDEs that currently support Dev Containers are Visual Studio Code (VS Code) and JetBrains IDEs, and we will be focusing on the VS Code Dev Containers in this blog post. The configuration of a dev container is described in a devcontainer.json file. The devcontainer.json file can be created manually or by using the VS Code Dev Container extension in a .devcontainer directory in the root directory of our project.

With the devcontainer.json in place, the project can now be opened in a dev container by using the VS Code Dev Container extension’s Reopen in Container command. It will look exactly like when it is opened locally on the host machine. VS Code extensions such as C/C++ (IntelliSense) and Cortex-Debug can be configured in the customizations section of the devcontainer.json so that these extensions will be installed in the dev container. By doing so, we can now navigate the code base and even debug the code in the dev container.The following is an example of a devcontainer.json that uses ubuntu:24.04 as a base image and installs Git, VSCode’s C/C++, and CMake Tools extensions:

{
	"image": "ubuntu:24.04",
	"features": {
		"ghcr.io/devcontainers/features/git": {},
	},
	"customizations": {
		"vscode": {
			"extensions": [
				"ms-vscode.cpptools",
				"ms-vscode.cmake-tools"
			],
		},
	}
}

When we open the VS Code integrated terminal (for MacBook users: command + shift + P -> View: Toggle Terminal), we are actually within the Docker container. Because of that, we can use the tools that were installed within the Docker container to interact with the code base. For example, if GCC is installed in the container, we can now build our code without having to install GCC on our host machine and the version of the GCC is fixed. VS Code has a nice documentation on how to set up and start using a dev container.

Devcontainer CLI

When we open a project, VS Code uses a CLI in the background to configure the dev container. The CLI is available for developers to create and use dev containers outside of the IDE. The following are the steps to get started on the devcontainer CLI:

// For MacBook users, install node via Homebrew
brew install node

// Install devcontainer CLI via npm
sudo npm install -g @devcontainers/cli

// Spin up a dev container
devcontainer up --workspace-folder <path-to-the-project>

// Run a command in the dev container
devcontainer exec --workspace-folder <path-to-the-project> <command>

Simplify Dockerfile

Dev containers make Dockerfiles modular. Instead of installing all the required IDEs, tools, and packages in a single Dockerfile, we can make use of the features section of the devcontainer.json by adding the tools we want to install in our Docker container. The features are links to the Docker images hosted on public or private Docker registries. A list of official dev container features can be found here. We can install IDEs or tools that cannot be found on the public Docker registry in a customized Docker image, but instead, by turning them into features that can be included in the dev container, we can have a much simpler base image. The customized features can then be reused in other projects as well.

Automatic Mounting of Filesystem

When we open a project with a dev container on an IDE, it automatically mounts the project’s filesystem within the Docker container. Modifications to the files on the IDE will reflect in both the local files on the host machine and the files in the Docker container. This can be achieved by running a Docker container with the -v or -volume flag by using the Docker CLI, but the dev container sets it up without having to type out the long Docker CLI command.

Conclusion

Docker itself has been a revolutionary tool. Dev containers further elevate the usage of Docker in software development. Besides the benefits of saving time and providing a consistent development environment provided by the nature of Docker containers, dev containers reduce the complexity of using Docker by integrating with IDEs and simplifying the Dockerfiles.

Dojo Five is dedicated to modernizing the embedded industry by using modern practices and tools such as Docker and dev containers. If you are interested in bringing your project to the next level, you can schedule a call with our team. Or, feel free to check out EmbedOps, our CI build platform. It’s free to sign up.

We look forward to hearing from you! -D5

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Laptop with some code on screen

I want to write my first embedded program. Where do I start?

The boom in the Internet of Things (IoT) commercial devices and hobbyist platforms like the Raspberry Pi and Arduino have created a lot of options, offering inexpensive platforms with easy to use development tools for creating embedded projects. You have a lot of options to choose from. An embedded development platform is typically a microcontroller chip mounted on a circuit board designed to show off its features. There are typically two types out there: there are inexpensive versions, sometimes called

Read More »
Medical device monitoring vitals

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part 1

IEC-62304 Software Lifecycle requires a lot of self-reflection to scrutinize and document your development processes. There is an endless pursuit of perfection when it comes to heavily regulated industries. How can you guarantee something will have zero defects? That’s a pretty hefty task. The regulatory approach for the medical device industry is process control. The concept essentially states that if you document how every step must be completed, and provide checks to show every step has been completed properly, you

Read More »
Operating room filled with medical devices

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part II

Part I provides some background to IEC-62304. Part II provides a slightly more in-depth look at some of the specifics. The IEC 62304 Medical Device Software – Software Lifecycle Processes looks into your development processes for creating and maintaining your software. The standard is available for purchase here. So what activities does the standard look at? Here are some of the major topics. For any given topic, there will be a lot more specifics. This will look at a few

Read More »