2b: Devcontainers and Codespaces
Devcontainers let us standardize the operating system and tools for a project, no matter where we run it.
We will put our environment setup into the project repository, instead of leaving it implicit (and often undocumented and not reproducible).
Our course repository has a .devcontainer/ folder.
That folder is why our Codespace can open with:
Research projects often work on one computer and then don’t quite work or don’t work the same on another.
Common causes:
A devcontainer is a project-level recipe for a development environment, using a container that provides a consistent Linux-based environment in a lightweight way.
It’s like a programmatic way of describing how our computer is set up.
The devcontainer files go in the repository along with our work. We can review, edit, commit, push, and share them like other project files.
That is the main idea: the setup is part of the project, not just something we happened to do on one computer.
Codespaces runs our environment in the cloud and opens it in VS Code Web. That’s a nice way to work, because it makes no assumptions about our local computer, other than that it has a web browser and internet connection.
It is important to note that we can run devcontainers locally by installing VS Code and Docker Desktop, and that’s often the way I work. But Codespaces is a great option on a computer with onerous IT permissions or for a course where we can do more fun content by not needing to troubleshoot local installs.
The main devcontainer file is usually:
It can specify the base image, features, VS Code extensions, and setup commands.
Note that we can actually have multiple devcontainer files in a project, though it’s beyond our scope for today.
In devcontainer.json, we often see:
image: the base container image;features: extra system tools;customizations: VS Code settings and extensions;postCreateCommand: setup commands after creation.pyproject.tomlThe devcontainer describes the broader computing environment.
pyproject.toml describes the Python project.
We usually need both.
Good candidates:
Usually not:
Changing the devcontainer recipe often means rebuilding or reopening the Codespace.
That can take a few minutes the first time, and it is usually faster for subsequent rebuilds because parts of the prior build are cached.
We’re updating the recipe, so we need to actually “bake” it with a rebuild.
The devcontainer files and any setup scripts they call should be in Git.
That way, the project carries its environment recipe along with the code, writing, and configuration.
Open the 2b activity page.