Luke M
Your next project in a devcontainer
2025-03-13
I recently decided to look into Devpod, which is a command-line tool (and graphical application) that makes it easy to develop within a container for each project.
This means that each project has its own development container, containing dev dependencies and configuration.
A quick overview
Dockerfiles are a set of instructions for building a container.
Docker-compose is a tool (and yaml specification) that allows you to orchestrate multiple containers.
Devcontainers are built from devcontainer.json
files, and specifically stand
up the development environment.
Benefits of Devcontainers
- None of the dependencies touch your system
- If you're using VSCode, it will automatically install extensions that are useful to the project
- If you are using Neovim, you can pass in a URL for your dotfiles git repository
- Onboarding other devs is seamless
- Using them teaches you Docker
A basic setup
Here is a basic setup that creates a dev container with Neovim installed using Homebrew on Debian.
{
"image": "mcr.microsoft.com/devcontainers/base:debian",
"features": {
"ghcr.io/devcontainers-contrib/features/neovim-homebrew": {}
},
"remoteEnv": {
"LANG": "en_US.UTF-8"
},
"forwardPorts": [8000]
}
My advice is to create a slimmed down version of your dotfiles, for use with devpods. I shamelessly stole most of mine from Mischa Vandenburg's dotfiles-devpod repository.
devpod up . --dotfiles https://github.com/lkdm/dotfiles-devpod --dotfiles-script setup
Devcontainer Features
Devpod containers with docker-compose
You can stand up other services with your dev container using a
docker-compose.yml
file. This is useful if what you're developing requires
other containers alongside it.
{
"dockerComposeFile": ["docker-compose.yml"],
"service": "app",
"runServices": ["db"],
"workspaceFolder": "/workspace"
// ...
}
Using production docker-compose
Notice how the dockerComposeFile
property is a list? Devpod uses the first
item in the list, and applies YML properties from each subsequent file as a
patch.
This means you can have a docker-compose.yml
for production in the root of
your project, and have a .devcontainer/docker-compose.yml
to make changes to
certain properties to make it fit for development.
services:
app:
environment:
- DB_SERVER=db
- DB_PORT=5432
- DB_NAME=postgres
- DB_USER=postgres
- DB_PWD=postgres
- LOGGING_APP=debug
- LOGGING_HTTP=info
ports:
- "58868"
db:
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres