Sachith Dassanayake Software Engineering Dev containers & reproducible environments — Migration Playbook — Practical Guide (Apr 11, 2026)

Dev containers & reproducible environments — Migration Playbook — Practical Guide (Apr 11, 2026)

Dev containers & reproducible environments — Migration Playbook — Practical Guide (Apr 11, 2026)

Dev containers & reproducible environments — Migration Playbook

body { font-family: Arial, sans-serif; line-height: 1.6; margin: 1em 2em; max-width: 900px; }
h2 { color: #2c3e50; }
h3 { color: #34495e; }
pre { background: #f4f4f4; padding: 1em; overflow-x: auto; border: 1px solid #ddd; border-radius: 4px; }
code { font-family: Consolas, monospace; }
p.audience { font-style: italic; font-weight: bold; color: #16a085; }
p.social { margin-top: 2em; font-size: 0.9em; color: #555; }
ul { margin-left: 1.4em; }

Dev containers & reproducible environments — Migration Playbook

Level: Intermediate software engineers

As of April 11, 2026 — guidance applicable to VS Code Dev Containers (stable from 2023 onwards), GitHub Codespaces, and Docker 24.x+

Introduction

Reproducible development environments are vital for reducing “works on my machine” issues and streamlining onboarding and CI/CD. Dev containers are a proven, modern approach to standardise environments via containerisation with declarative configs. This playbook guides you through migrating existing local development setups or legacy scripts into dev containers efficiently and reliably.

Prerequisites

Before starting the migration, ensure you have the following in place to align with current best practices:

  • Docker Engine 24.x+ installed and configured for your platform.
  • Visual Studio Code (VS Code) 1.80+</strong with the Remote – Containers extension installed.
  • Access to your project source code and existing environment scripts or Dockerfiles.
  • Basic familiarity with Dockerfile syntax, docker-compose, and VS Code workspace settings.

For teams, consider adopting a version control branch for the container migration to minimise disruption.

Hands-on Steps

1. Assess your current environment

Catalogue tools, language runtimes, package managers, environment variables, and scripts your current environment uses. Check for:

  • Installed versions of languages/frameworks (e.g. Node.js, Python, etc.).
  • OS-level dependencies or shared services.
  • Scripts that automate setup.

2. Choose a base image and create devcontainer.json

Pick a base image aligned with your stack—official distro images like ubuntu, language-specific variants such as mcr.microsoft.com/vscode/devcontainers/python (stable and maintained by Microsoft), or lightweight variants like Alpine (beware Alpine’s musl libc differences if relying on native extensions).

Create a .devcontainer/devcontainer.json in your repository. For example:

{
  "name": "Example Node.js Dev Container",
  "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:20",
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
      ]
    }
  },
  "postCreateCommand": "npm install"
}

This defines the container image, installs VS Code extensions, and runs package installation after creation.

3. Add Dockerfile or use an existing image

If you require OS-level dependencies or custom setups, create a Dockerfile inside .devcontainer/. Minimal example installing system libraries for a Python project:

# .devcontainer/Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/python:3.12

RUN apt-get update && apt-get install -y 
    build-essential 
    libssl-dev 
    && rm -rf /var/lib/apt/lists/*

Then, update devcontainer.json accordingly:

{
  "name": "Python Custom Dev Container",
  "build": {
    "dockerfile": "Dockerfile",
    "context": "."
  },
  "settings": {
    "python.pythonPath": "/usr/local/bin/python"
  },
  "postCreateCommand": "pip install -r requirements.txt"
}

4. Configure workspace and environment variables

In devcontainer.json, specify environment variables, forwarded ports, and mounts if needed:

{
  "name": "Full featured devcontainer",
  "build": { "dockerfile": "Dockerfile" },
  "forwardPorts": [3000, 8000],
  "remoteEnv": {
    "NODE_ENV": "development",
    "API_URL": "http://localhost:5000"
  },
  "mounts": [
    "source=${localWorkspaceFolder}/data,target=/data,type=bind"
  ]
}

This ensures the container matches the expected runtime configuration and accesses local data.

5. Test your dev container in VS Code

Open VS Code in the project folder and use the command palette to select Remote-Containers: Reopen in Container. This will build and launch your containerised environment. Verify that:

  • All tools and extensions work.
  • Language servers or debuggers initialise correctly.
  • The build and setup commands complete without errors.

Common Pitfalls

  • Using overly large base images: Can lead to slow builds and large container sizes. Prefer language-devcontainer images or slim variants where possible.
  • Overriding default entrypoints incorrectly: This may break VS Code’s remote connection setup. Only modify if well understood.
  • Hardcoding local paths: Avoid absolute paths specific to your machine; use workspace-relative paths and VS Code variables.
  • Missing post-create steps: Forgetting dependency installation leads to runtime errors.
  • Ignoring platform differences: Windows, Mac, and Linux handle volume mounts, permissions, and line endings differently—test accordingly.

Validation

Verify reproducibility by running these checks:

  • Clean build: Clone your repo into a fresh directory/machine, build your dev container, and confirm the environment mirrors expected versions and setup.
  • Port availability: Run your development server and check forwarded ports function externally.
  • Extension functionality: Confirm VS Code extensions activate and behave as expected in the container.
  • Source consistency: Ensure source code changes persist correctly and file system syncing is seamless.

Checklist / TL;DR

  • Inventory current environment dependencies and tools.
  • Select appropriate base image (official VS Code devcontainers recommended).
  • Create devcontainer.json and optionally Dockerfile under .devcontainer/.
  • Define workspace settings, forwarded ports, environment variables.
  • Install required extensions in devcontainer.json.
  • Test container startup and development workflows inside VS Code.
  • Watch for typical pitfalls (bloat, path issues, platform-specific quirks).
  • Validate by reproducing environment from clean clone/build.

When to choose dev containers vs alternatives

Dev containers shine when you want integrated, ephemeral but consistent environments tightly coupled with VS Code or GitHub Codespaces. They facilitate rapid onboarding and consistent CI/CD pipelines with easy configuration.

Alternative approaches include plain Docker Compose setups (more flexible for non-code services), virtual machines (heavier but closer to your production environment), or environment management tools like asdf or direnv (lighter but less isolated). Choose based on your team’s workflow, toolchain, and need for isolation versus flexibility.

References

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Post