Using DooD in a devcontainer like a true pro!
Theodor Heiselberg

Theodor Heiselberg @sukkergris

About: Developer since 2008

Location:
Denmark
Joined:
Jan 11, 2024

Using DooD in a devcontainer like a true pro!

Publish Date: Aug 23
0 0

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
Enter fullscreen mode Exit fullscreen mode

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"
    }
}

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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 :)

Comments 0 total

    Add comment