Skip to content

How to Configure GitHub Codespaces (devcontainer.json)

DodaTech 2 min read

In this tutorial, you'll learn about How to Configure GitHub Codespaces (devcontainer.json). We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Your GitHub Codespace starts but is missing essential tools, language runtimes, VS Code extensions, or dependencies. Without a .devcontainer/devcontainer.json configuration file, every new Codespace starts from the universal base image and you must manually install all tools, extensions, and dependencies each time. This wastes 10-15 minutes per workspace and leads to inconsistent development environments across the team. Some team members may have different tool versions, causing "works on my machine" bugs.

Quick Fix

1. Create the devcontainer directory and config file

mkdir -p .devcontainer

.devcontainer/devcontainer.json:

{
    "name": "My Project Dev Environment",
    "image": "mcr.microsoft.com/devcontainers/universal:2",
    "features": {
        "ghcr.io/devcontainers/features/node:1": {
            "version": "20"
        },
        "ghcr.io/devcontainers/features/python:1": {
            "version": "3.12"
        },
        "ghcr.io/devcontainers/features/docker-in-docker:1": {}
    },
    "customizations": {
        "vscode": {
            "extensions": [
                "esbenp.prettier-vscode",
                "dbaeumer.vscode-eslint",
                "ms-python.python",
                "github.copilot",
                "streetsidesoftware.code-spell-checker]
            ],
            "settings": {
                "editor.formatOnSave": true,
                "editor.defaultFormatter": "esbenp.prettier-vscode",
                "editor.rulers": [100],
                "files.trimTrailingWhitespace": true
            }
        }
    },
    "postCreateCommand": "npm install && npm run build",
    "forwardPorts": [3000, 5000],
    "portsAttributes": {
        "3000": {
            "label": "Web App",
            "onAutoForward": "openBrowser"
        },
        "5000": {
            "label": "API Server",
            "onAutoForward": "notify"
        }
    }
}

The features section installs specific language runtimes and tools. The customizations.vscode section pre-installs extensions and configures editor settings. The postCreateCommand runs after the container is created to install project dependencies.

2. Use a Dockerfile for a fully custom base image

./devcontainer/Dockerfile:

FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04

RUN apt-get update && apt-get install -y \
    postgresql-client \
    redis-tools \
    ripgrep \
    htop \
    && rm -rf /var/lib/apt/lists/*

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y nodejs

Reference the Dockerfile in devcontainer.json:

{
    "name": "Custom Dev",
    "build": {
        "dockerfile": "Dockerfile"
    },
    "forwardPorts": [5432],
    "portsAttributes": {
        "5432": { "label": "PostgreSQL" }
    }
}

3. Rebuild the Codespace after changing the config

Open the VS Code command palette in the Codespace:

Ctrl+Shift+P → "Codespaces: Rebuild Container"

The rebuild takes 1-2 minutes and applies all configuration changes.

4. Verify the environment has everything you need

node --version
python3 --version
docker --version
psql --version

Expected output:

v20.11.0
Python 3.12.1
Docker version 25.0.0
psql (PostgreSQL) 16.1

5. Add lifecycle hooks for fine-grained control

{
    "onCreateCommand": "echo 'Container created — initial setup'",
    "updateContentCommand": "echo 'Repository content updated'",
    "postCreateCommand": "npm install && npm run build",
    "postStartCommand": "echo 'Container started — ready for development'"
}

The hooks run in this order: onCreateCommand (once), updateContentCommand (on content change), postCreateCommand (after content), postStartCommand (every start).

Prevention

  • Commit .devcontainer/devcontainer.json to the Repository root from the first day of the project
  • Pin tool versions explicitly in the features section (e.g., "version": "20")
  • Use postCreateCommand for project-specific setup — install, build, database Migration
  • Forward only the ports your application actually needs to keep the port list manageable
  • Test the devcontainer configuration on a fresh clone to verify it works before asking the team to use it

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro