Yes - It is possible to use DooD in a devcontainer
When setting up a real-world devcontainer, you often need more than just a simple “hello world” example. In practice, most development environments rely on several running containers at once — databases, caches, and supporting services. For that, it’s often easier to use Docker-out-of-Docker (DooD) so your devcontainer can talk to the host’s Docker daemon directly.
In this post, we’ll set up a devcontainer environment that uses:
    • A custom Dockerfile for building the development container.
    • docker-compose to orchestrate the environment.
    • DooD via the mounted Docker socket, allowing us to run other containers from inside the devcontainer.
This gives you a solid foundation for building a “real-life” dev environment instead of the typical examples that don’t scale.
The file system
.devcontainer
   ├── devcontainer.json   # Main devcontainer config
   ├── docker-compose.yml  # Orchestration file
   ├── Dockerfile.debian   # Custom base image for the devcontainer
   └── .env                # Environment variables
devcontainer.json
Here we enable the docker-outside-of-docker feature and configure environment variables:
{
    "name": "Testcontainers Debian dev-environment",
    "dockerComposeFile": "docker-compose.yml",
    "service": "dev",
    "workspaceFolder": "/workspace",
    "remoteUser": "root",
    "features": {"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}},
    "containerEnv": {
        "TZ": "Europe/Copenhagen",
        "TESTCONTAINERS_HOST_OVERRIDE": "host.docker.internal"
    }
}
docker-compose.yml
The compose file mounts the workspace and the host’s Docker socket:
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile.debian
    volumes:
      - ..:/workspace:cached
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - internal
    command: ["sleep", "infinity"]
networks:
  internal:
    driver: bridge
Dockerfile.debian
We start from a slim .NET SDK base and install the necessary tooling (and some..):
# Use a base Debian image
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
# Set noninteractive mode to avoid prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
# Create docker group and add root to it
RUN groupadd -r docker && usermod -aG docker root
# Install dependencies
# Added ca-certificates as it's often needed for https downloads and the dotnet install script might rely on it
RUN apt-get update && \
    apt-get install -y \
        git \
        dos2unix \
        docker.io \ <-- MINIMUM
        stow \
        zsh \
        tree \
        clang \
        jq \
        unzip \
        xclip \
        wget \
        curl \
        ca-certificates \
        apt-transport-https \
        software-properties-common && \
        rm -rf /var/lib/apt/lists/*
RUN dotnet tool install Nuke.GlobalTool --global
ENV PATH="$PATH:~/.dotnet/tools"
# Install .NET Runtime using the official script.
# This script handles architecture detection for you.
RUN curl -L https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh && \
    chmod +x /tmp/dotnet-install.sh && \
    /tmp/dotnet-install.sh --version 9.0.4 --runtime dotnet && \
    rm /tmp/dotnet-install.sh
Now run the container and test that you have access to your host's docer environment:
That's it!
You now have a development environment capable using DooD and eg. running devcontainers like a true pro!
Next steps
Add your own services to the docker-compose.yml and extend the Docker.debian with your own installs :)
 


 
    
Top comments (0)