Dev Container fundamentals
Published August 26, 2026 · Updated August 27, 2026
View last change
c444ec4 — feat: Added edit date.
A Dev container gives you the possibility to run a container as a fully functional development environment, with all the features it needs. You can use a Dev container to run an application, different tools, libraries or runtimes you need for running a codebase.
- A
libraryis code that is already written by somebody, and contains functions. From your code you call the functions from the library. Runtimeprovides the environment the program needs to execute.- A
codebaseis the project containing all the code, configuration files and related assets.
The Dev container specification is built to provide rules of how to set up the Dev container, and extends with configuration files like the Dockerfile.
Specificationis the rules. It describes what something should be or do.
Problem it solves
Before containers were used, developers worked directly on their local machine when developing code. At a certain time each developer’s machine is different, has different tools installed, uses different versions and has different settings.
When another developer needs to check the code, or needs to work on the same codebase this can be a pain in the ass to set the environment up on their local machine, installing all the tools necessary, and fixing any compatibility errors due to multiple overlapping versions of libraries and runtimes or even a different OS.
With Dev Containers you can specify a container environment with all the necessary tools, libraries and runtime to run, and work on the codebase and provide an instruction to start up the dev container.
Because devcontainer.json can be used by the devcontainer CLI in CI pipelines, you can run the exact same environment for automatic tests, for example with GitHub Actions. This tight integration between local dev and CI makes it easy to ship small changes multiple times a day, instead of working alone for weeks and pushing one large commit that causes conflicts and bugs.
How it works
To run a container you need a container runtime, like Docker, and a Dev container runtime like VSCode or DevPod.
To set up a devcontainer.json you can do this for example through VSCode.
- Install VSCode
- Install the VSCode extension
Dev Containers
To create a Dev container:
- Type in the search bar
> Dev Container: New Dev Container - Select a container image from the list, for example
python 3 - Select
Create Dev Container python
VSCode will now start to create the Dev container for you. When the Dev container is created it will automatically connect to it. You are now working directly in the container.
In the background the extension creates a devcontainer.json file in the .devcontainer folder inside the project folder.
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:3-3.14-trixie"
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
In the above example the image will be built based on the image specified. In this case mcr.microsoft.com/devcontainers/python:3-3.14-trixie. After the image is built the container will be created and the provided settings will be applied to the container.
For example you can add tools you want to install into the Dev container by adding them to the features section.
Some containers already have features installed in the images. You can see the images and specifications on https://github.com/devcontainers/images/tree/main/src/.
python:3-3.14-trixiefor example already includes node, git and zsh.
Because you run the Dev container with VSCode, it will install a version of Visual Studio Code Server into the remote container so you can connect your local VSCode to the Dev container to work on code.
You can also create the necessary files yourself. When VSCode detects them in your project folder it will ask to build or start the Dev container.
Creating the devcontainer.json only
With VSCode you also can create the necessary devcontainer.json file only.
> Dev Container: Add Container Configuration Files..to only create the devcontainer.json- Choose to add the configuration to the workspace
- Select the image you like to use (I used PowerShell for this example)
- Add some features if you like, for example the
Azure CLI - VSCode will create the configuration file
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/powershell
{
"name": "PowerShell",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/powershell:lts-debian-11",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "true",
"username": "vscode",
"upgradePackages": "false",
"nonFreePackages": "true"
},
"ghcr.io/devcontainers/features/azure-cli:1": {
"installBicep": true,
"version": "latest",
"bicepVersion": "latest"
}
},
"postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"",
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.defaultProfile.linux": "pwsh"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["ms-vscode.powershell"]
}
}
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
After creating the configuration VSCode will detect the configuration file and ask to reopen in a Dev container.
When the container is created the following will happen:
- The image will be built from
mcr.microsoft.com/powershell:lts-debian-11 - The configuration specifies
common-utilsto install zsh, set up a non-root user. - The following features will be installed:
- Zsh
- azure-cli, with Bicep
- After the container is built the
postCreateCommandwill run. In this case it will run the commandsudo chsh vscode -s \"$(which pwsh)\". This command will change the shell for the user VSCode to whatever returns from the commandwhich pwsh, which in our case will be the location of the PowerShell shell. - In the customizations property some VSCode PowerShell settings will be applied, like installing the PowerShell extension.
More info about common-utils can be found on https://github.com/devcontainers/features/tree/main/src/common-utils
When I’d reach for it
I will reach for Dev Containers anytime I’m in need of a clean or pre-configured development environment, when I try out some new features or want to develop some PowerShell scripts. Dev containers make it also possible to work on my project regardless of the machines I’m using.
How it compares to NixOS
NixOS provides a Nix package manager that installs each package on a separate, hash-addressed path and uses that to build an environment with symlinks and references to the exact versions you declare. It runs on your own system.
There is also a NixOS distribution you can run your machine on. This will give you the possibility to make your whole machine reproducible.
So where Nix provides you with a development environment by changing your shell and environment variables, Dev Containers provide you with a whole isolated dev environment running in a container and different Linux versions, therefore Dev Containers will give you some more overhead due to image sizes.
Links
- Dev Container website https://containers.dev/
- Image location managed by Microsoft https://github.com/devcontainers/images
- Details of the common-utils https://github.com/devcontainers/features/tree/main/src/common-utils
Questions or thoughts about this post? Reach me at jacky@tenrok.nl or on LinkedIn.