Must-Have Tools and Services for Developers Using DevContainers in VS Code
The Development Container Specification (DevContainers) is a fantastic tool that makes development easier by adding common settings, tools, and configurations to existing formats. This spec aims to offer a simple, single-container option for coding environments or for continuous integration and testing. In this article, we'll dive into the different tools and services that make DevContainers a must-have in today's development workflows.
What are DevContainers?
DevContainers are essentially Docker containers configured specifically for development purposes. They encapsulate the entire development environment, including the operating system, tools, libraries, and settings, ensuring consistency across different development setups. This approach eliminates the "it works on my machine :(" problem by providing a standardized environment for all developers.
Key Features of DevContainers
Consistency: DevContainers ensure that all developers work in the same environment, reducing discrepancies and integration issues.
Portability: Since DevContainers are based on Docker, they can run on any system that supports Docker, making them highly portable.
Isolation: Each DevContainer is isolated from the host system, preventing conflicts between different projects and their dependencies.
Reproducibility: DevContainers can be versioned and shared, allowing teams to reproduce the exact development environment at any time.
Supporting Tools and Services
To fully leverage the power of DevContainers, several tools and services can be integrated into the workflow. These tools enhance the functionality, usability, and efficiency of DevContainers.
It's time to get our hands dirty, so let's follow these simple steps, and at the end, I will explain what I encountered during my journey unveiling this fascinating set of tools:
1. Visual Studio Code (VS Code)
VS Code is a popular code editor that offers excellent support for DevContainers through its Remote - Containers extension (VS extension code ID: ms-vscode-remote.vscode-remote-extensionpack)
Visual Studio Code Remote Development Extension Pack
This extension allows developers to open any folder inside a container, providing a seamless development experience. Key features include:
- Folder Configuration: The following is the folder structure that I recommend
Container Configuration: This is where you customize DevContainers using definitions like:
- name, forwardports, init, privileged, and many more that you can check here in the official documentation: (Dev Container metadata reference)
Hopefully, with this diagram, you can easily see how to proceed. If your mind works like mine, this will be helpful for sure :)
- ADVICE 1: Take into consideration the RECOMMENDED boxes. They will help you avoid pain and suffering during your configuration. Believe me, it will save you time.
- Of course, you can proceed by creating a regular Dockerfile and installing all the required software for your environment, but the fundamental difference between doing that and using DevContainers with VS Code is that you will have a more dynamic way to modify "on the fly" the extensions that you require for your environment and rebuild it. Then, in a matter of seconds (depending on your laptop, of course), you will have your DevContainer environment updated!
The files content that you created according to the diagram are the next:
devcontainer.json
{
"name": "rolling desktop",
"dockerFile": "Dockerfile",
"runArgs": [
"--privileged",
"--network=host"
],
"workspaceMount": "source=${localWorkspaceFolder},target=/${localWorkspaceFolderBasename},type=bind",
"workspaceFolder": "/${localWorkspaceFolderBasename}",
"mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.bash_history,target=/home/vscode/.bash_history,type=bind"
],
"customizations": { //This works in the same way that features block
"vscode": {
"extensions": [
"ms-github.copilot",
"ms-kubectl-tools.kubectl",
"cloudcode.active-kubeconfig",
"ms-prettier.prettier-vscode",
"redhat.vscode-yaml",
"googlecloudtools.cloudcode",
"oderwat.indent-rainbow",
"kennylong.kubernetes-yaml-formatter",
"ms-kubernetes-tools.vscode-kubernetes-tools"
]
}
},
"features": { //features and customizations could live together
"ghcr.io/devcontainers/features/aws-cli:1": {},
"ghcr.io/devcontainers/features/azure-cli:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/terraform:1": {},
"ghcr.io/dhoeric/features/google-cloud-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
"ghcr.io/devcontainers-contrib/features/kubectl-asdf:2": {
"version": "latest"
}
},
"postCreateCommand": "sudo apt-get update && sudo apt-get install -y"
}
devcontainer-template.json
{
"version": "1", //change the content for whatever you like :)
"publisher": "ContourKDE",
"description": "basic devcontainer for developers"
}
Dockerfile
FROM ubuntu:20.04
# Add vscode user with same UID and GID as your host system
# (copied from https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user#_creating-a-nonroot-user)
ARG USERNAME=contoukde
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# Switch from root to user
USER $USERNAME
# Add user to video group to allow access to webcam
RUN sudo usermod --append --groups video $USERNAME
# Update all packages
RUN sudo apt update && sudo apt upgrade -y
# Keep going with whatever you like
Extensions: Install and use VS Code extensions inside DevContainers. You can do this in two different ways:
- With the block "customizations" (The easy way): You do not need to know the extension ID. Simply open the devcontainer.json file in VS Code, then in the side bar, look for the extensions button. Select the extension you want to add to the devcontainer, click on "manage," and then "Add to devcontainer.json."
The other way (With the Available Dev Container Features): With this, you have to use the "features" block. You have to go to the features website and look for the extensions that you want to be installed in your devcontainer. Remember, sometimes these extensions added in this way fail, so test one by one if you want to proceed with the features block.
2. Docker or Docker Compose?
Docker is the underlying technology that powers DevContainers. It provides the containerization platform that allows DevContainers to run consistently across different environments. It depends on each scenario, but if you want to deploy multiple containers at once to test (for example, a 3-tier architecture), use Docker Compose. In this post, we are going to stick to a simple Dockerfile definition to avoid adding complexity to the basic devcontainer explanation that we would like to keep.
3. Other scenarios
Of course, devcontainers could be used in other different scenarios like in a CI/CD for testing, but for now, we will keep the explanation under the KISS concept: Keep it Simple Stupid. If this works, I hope you will find the next posts also interesting because we will add more complexity and other features.
Conclusion
ADVICE 2: I have tested this on 2 different laptops:
MacOS (Apple M1 Max Sonoma 14.5): Sometimes it works, sometimes it doesn't. There are also limitations with some extensions (many of them, unfortunately). I managed to work around many of these failures by using a plain Ubuntu image in my Dockerfile and installing the different software as Docker instructions. However, as I said, that wouldn't be different from a manual configuration, right? The only difference is that you could manage to install several extensions in your environment. I recommend you install them one by one to debug better.
Pop!_OS 22.04 LTS (Basically an Ubuntu 22.04 with superpowers): It works well from the beginning. I recommend you create a fresh folder and start from there. I did have weird issues not finding the workspace I was working in because of this. Then, I got rid of these errors by starting from a new folder (not a subfolder, by the way).
DevContainers offer a robust solution for creating consistent, portable, and reproducible development environments. By integrating supporting tools and services such as VS Code, Docker, GitHub Codespaces, and CI/CD tools, developers (like me) can significantly enhance their productivity and streamline their workflows. As the development landscape continues to evolve, DevContainers will undoubtedly play a crucial role in shaping the future of software development.
BUY ME A COFFEE!
Subscribe to my newsletter
Read articles from William Javier Acelas Granados directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by