Docker-in-Docker (DinD) Environment: Because Why Not Run Containers Inside Containers?

July 13, 2024

DinDMeme

Ever wanted to nest containers inside other containers? Welcome to Docker-in-Docker (DinD)—where containers go Inception on themselves!

DinDIsolation

Unraveling Docker-in-Docker (DinD)

In a nutshell, DinD lets you achieve container inception. It's like a Russian doll of Docker: containers within containers, each with its own universe of apps and dependencies.

Why Docker-in-Docker (DinD)?

So, why dive into this containerized rabbit hole? Here’s why DinD shines brighter than a supernova:

  1. Testing/Building Docker Images: Perfect for testing/building Docker images in a pristine, isolated environment—no more "but it worked on my machine" excuses!
  2. CI/CD Pipelines: Keep your pipelines neat and efficient within Docker. DinD ensures what works in development also sails smoothly into production.
  3. Kubernetes Environments: Need containers within Kubernetes pods? DinD supports nested pods—a Kubernetesception for running docekr containers within Kubernetes pods.

Setting Up Docker-in-Docker (DinD)

Setting up DinD is a breeze, especially on Ubuntu. Here’s a quick guide to get you started:

  1. Install Docker: If Docker isn't already installed on your host, run this command to fetch it like a pro shopper on Black Friday:
curl -fsSL https://get.docker.com | sh
  1. Crafting a Dockerfile for DinD: Imagine crafting a Lego spaceship—creating a Dockerfile for your DinD adventure is just as delightful:
# Using Ubuntu 24.04 as the launchpad
FROM ubuntu:24.04

# Installing essential supplies
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    gnupg \
    iptables \
    supervisor

# Summoning Docker with the elegance of a magic spell
RUN curl -fsSL https://get.docker.com | sh

# Infusing NVIDIA Container Toolkit for GPU wizardry
RUN curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
    && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
    && apt-get update \
    && apt-get install -y nvidia-container-toolkit \
    && nvidia-ctk runtime configure --runtime=docker \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Unveiling the entrypoint script and overseeing Supervisor's watchful eye
COPY entrypoint.sh /usr/local/bin/
COPY supervisor/ /etc/supervisor/conf.d/

# Empowering the entrypoint script with executable powers
RUN chmod +x /usr/local/bin/entrypoint.sh

# Creating a sanctuary for Docker's data vault
VOLUME /var/lib/docker

# Guiding the container to its starting point
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

# When all else fails, let's have a bash!
CMD ["bash"]
  1. Entrypoint Script: Every container needs guidance. Here’s an entrypoint script to shepherd your DinD container to greatness:
#!/bin/bash

# Function to patiently wait for a process to awaken
function wait_for_process() {
    local max_time_wait=30
    local process_name="$1"
    local waited_sec=0
    while ! pgrep "$process_name" >/dev/null && ((waited_sec < max_time_wait)); do
        echo "Waiting for $process_name to stir from its slumber..."
        echo "Time elapsed: $waited_sec seconds of $max_time_wait seconds"
        sleep 1
        ((waited_sec++))
        if ((waited_sec >= max_time_wait)); then
            return 1
        fi
    done
    return 0
}

echo "Initiating Supervisor mode..."
supervisord -n >> /dev/null 2>&1 &

echo "Awaiting the majestic awakening of dockerd..."
wait_for_process dockerd
if [ $? -ne 0 ]; then
    echo "Error: dockerd failed to rouse after maximum waiting time"
    exit 1
else
    echo "dockerd is now gracefully awake"
fi

# It's showtime! Execute the awaited command
exec "$@"
  1. Supervisor Configuration: Keep your DinD container in check with a Supervisor configuration:
[program:dockerd]
command=/usr/bin/dockerd
autostart=true
autorestart=true
stderr_logfile=/var/log/dockerd.err.log
stdout_logfile=/var/log/dockerd.out.log

Dive into Docker-in-Docker (DinD)!

docker build -t dind-magic .
docker run -it --privileged --gpus all --name dind-magic dind-magic

Why settle for one layer of abstraction when you can have two? Embrace Docker-in-Docker and let your containers nest within containers, creating a universe of containerized wonders!

Too busy to DIY? We've got you covered!

Explore our repository for a ready-made solution(s)—yes, we have a bunch of surprises too! Because who needs to reinvent the container when you can just grab it off the shelf?

And for those extra lazy days, fire up your terminal and run:

docker run -it --rm --privileged ghcr.io/prasad89/dind-ubuntu-nvidia

No setup, no hassle—just Docker-in-Docker magic at your fingertips.

prasad89 (GitHub)

Related:

← Back to home