Complete Guide to Docker-in-Docker
This page provides a comprehensive guide to Docker-in-Docker (DinD) mode, including principles, configuration, best practices, and security analysis.
Note: Run profiles should be under
runs.<name>in~/.manyoyo/manyoyo.json; use absolute paths forenvFileand map style forenv.
What is Docker-in-Docker
Docker-in-Docker refers to the technology of running a Docker daemon inside a Docker container, allowing you to create and manage other containers within a container.
Use Cases
- CI/CD Pipelines: Building and testing Docker images in containerized CI environments
- Development Environment Isolation: Providing independent container runtime environments for each project
- Multi-tenant Container Platforms: Providing isolated container environments for different users
- Containerized Application Testing: Testing applications that require container support
DinD Implementation in MANYOYO
MANYOYO provides two container nesting solutions:
- Docker-in-Docker (dind): True container nesting, secure isolation ✅ Recommended
- Socket Mount (sock): Mount host socket, dangerous but performant ⚠️ Use with caution
This document primarily covers dind mode.
Quick Start
Basic Usage
# Start container in dind mode
manyoyo run -m dind -x /bin/bash
# Use Podman inside the container (works out of the box)
podman ps -a
podman run hello-world
podman build -t myimage .
# Or use Docker (need to start dockerd first)
nohup dockerd &
sleep 10
docker ps -aConfiguration File Method
# Create dind configuration
cat > ~/.manyoyo/manyoyo.json << 'EOF'
{
"runs": {
"dind": {
"containerName": "my-dind",
"containerMode": "dind",
"envFile": ["/abs/path/anthropic_claudecode.env"],
"yolo": "c"
}
}
}
EOF
# Start using the configuration
manyoyo run -r dindHow It Works
Architecture Diagram
Host Machine
└─ MANYOYO Outer Container (dind mode)
├─ Podman/Docker daemon (independent runtime)
├─ AI Agent (can operate containers)
└─ Nested Containers (completely isolated)
├─ Application Container A
├─ Application Container B
└─ Application Container CTechnical Implementation
MANYOYO's dind mode is based on the following technologies:
- Privileged Container: The outer container needs certain privileges to run container runtimes
- Independent Storage: Nested containers use an independent storage backend
- Network Isolation: Nested containers have their own network stack
- Process Isolation: Complete PID namespace isolation
Podman vs Docker
Podman (Recommended)
Advantages:
- Works out of the box, no need to manually start daemon
- Rootless mode, more secure
- Compatible with Docker CLI commands
- Lightweight, less resource usage
Usage:
# Enter dind container
manyoyo run -m dind -x /bin/bash
# Use Podman directly
podman ps -a
podman images
podman run -d nginx
podman build -t myapp .Docker
Advantages:
- Full Docker ecosystem support
- Docker Compose support
- Some tools require Docker specifically
Usage:
# Enter dind container
manyoyo run -m dind -x /bin/bash
# Start dockerd (run in background)
nohup dockerd > /var/log/dockerd.log 2>&1 &
# Wait for startup to complete
sleep 10
# Verify
docker version
docker ps -a
# Use Docker
docker run hello-world
docker build -t myapp .Complete Examples
Example 1: AI-Assisted Containerized Application Development
# 1. Create dind configuration
cat > ~/.manyoyo/manyoyo.json << 'EOF'
{
"runs": {
"dind-dev": {
"containerName": "my-dind-dev",
"containerMode": "dind",
"envFile": ["/abs/path/anthropic_claudecode.env"],
"volumes": [
"~/.docker:/root/.docker:ro"
],
"yolo": "c"
}
}
}
EOF
# 2. Start AI-assisted development
manyoyo run -r dind-dev
# 3. AI can help with:
# - Writing Dockerfile
# - Building images
# - Running container tests
# - Debugging container issues
# 4. Check after exiting
manyoyo run -n my-dind-dev -x /bin/bash
# 5. View containers and images created by AI
podman ps -a
podman imagesExample 2: CI/CD Pipeline
# 1. Create CI run profile
cat > ~/.manyoyo/manyoyo.json << 'EOF'
{
"runs": {
"ci": {
"containerName": "my-ci",
"hostPath": "/abs/path/myproject",
"containerPath": "/abs/path/myproject",
"containerMode": "dind",
"env": {
"CI": "true",
"NODE_ENV": "test"
}
}
}
}
EOF
# 2. Run CI tasks
manyoyo run -r ci -x /bin/bash
# 3. Run tests inside the container
$ npm install
$ npm test
# 4. Build Docker image
$ podman build -t myapp:test .
# 5. Run integration tests
$ podman run --rm myapp:test npm run integration-test
# 6. Cleanup
$ podman rm -f $(podman ps -aq)Example 3: Multi-stage Build Testing
# Enter dind container
manyoyo run -m dind -x /bin/bash
# Create test Dockerfile
cat > Dockerfile.test << 'EOF'
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EOF
# Build multi-stage image
podman build -f Dockerfile.test -t webapp:test .
# Run test
podman run -d -p 8080:80 webapp:test
# Test access
curl http://localhost:8080
# Cleanup
podman stop $(podman ps -q)Configuration Options
Environment Variables
# Docker configuration
export DOCKER_HOST=unix:///var/run/docker.sock
export DOCKER_BUILDKIT=1
# Podman configuration
export CONTAINER_HOST=unix:///run/podman/podman.sockStorage Configuration
# Configure Podman storage inside the container
mkdir -p ~/.config/containers
cat > ~/.config/containers/storage.conf << 'EOF'
[storage]
driver = "overlay"
graphroot = "/var/lib/containers/storage"
[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"
EOFNetwork Configuration
# Create custom network
podman network create mynetwork
# Run container using custom network
podman run --network mynetwork -d nginxPerformance Optimization
1. Use Build Cache
# Podman
podman build --layers -t myapp .
# Docker
docker build --cache-from myapp:latest -t myapp .2. Multi-stage Parallel Build
FROM node:22 AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:22 AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html3. Use BuildKit
# Enable BuildKit (faster builds)
export DOCKER_BUILDKIT=1
docker build -t myapp .Security Analysis
DinD vs Socket Mount Security Comparison
| Feature | DinD Mode | Socket Mount Mode |
|---|---|---|
| Container Isolation | ✅ Complete isolation | ❌ Can access host containers |
| Image Isolation | ✅ Independent image registry | ❌ Shares host images |
| Container Escape Risk | ⭐⭐⭐⭐ Low | ⭐ High |
| Data Leak Risk | ⭐⭐⭐⭐ Low | ⭐ High |
| Malicious Operation Impact | Limited to outer container | Can affect host |
| Performance Overhead | Yes (independent runtime) | None |
Security Best Practices
1. Limit Resource Usage
# Limit CPU and memory
manyoyo run -m dind -x "podman run --cpus=1 --memory=512m myapp"2. Use Non-privileged Mode (if possible)
# Podman rootless mode (more secure)
podman run --security-opt=no-new-privileges myapp3. Scan Images for Security Vulnerabilities
# Use Trivy to scan
podman run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image myapp:latest4. Regular Cleanup
# Clean up unused resources
podman system prune -a --volumesTroubleshooting
Docker daemon Fails to Start
Problem: dockerd command cannot start
Solution:
# Check logs
tail -f /var/log/dockerd.log
# Start manually and view errors
dockerd --debug
# Clean up old socket
rm -f /var/run/docker.sockPodman Permission Issues
Problem: Permission denied error
Solution:
# Check user namespace
podman unshare cat /proc/self/uid_map
# Reset Podman
podman system reset
# Check storage configuration
podman infoImage Pull Fails
Problem: Unable to pull images
Solution:
# Check network
ping -c 3 docker.io
# Configure image mirror
mkdir -p /etc/containers
cat > /etc/containers/registries.conf << 'EOF'
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "mirror.example.com"
EOF
# Or use proxy
export HTTP_PROXY=http://proxy:8080
export HTTPS_PROXY=http://proxy:8080Storage Space Insufficient
Problem: Disk space insufficient
Solution:
# Check storage usage
podman system df
# Clean up unused resources
podman system prune -a --volumes
# Check nested container usage
podman ps -a --sizeLimitations and Considerations
Known Limitations
- Performance Overhead: Nested containers are 10-30% slower than direct containers
- Disk Usage: Independent image storage increases disk usage
- Network Complexity: Multi-layer networking may lead to complex configuration
- Some Features Not Supported: Some advanced Docker features may be unavailable
Considerations
- Exit Cleanup: Removing the outer container will clean up all nested containers
- Data Persistence: Important data should be mounted to the outer container
- Network Ports: Nested container ports need to be mapped twice
- Resource Limits: Resource limits of the outer container will affect nested containers
Comparison with Other Solutions
DinD vs Kaniko
Kaniko: Daemonless container image build tool
| Feature | DinD | Kaniko |
|---|---|---|
| Requires Privileges | Yes | No |
| Build Speed | Fast | Slower |
| Cache Support | Full | Limited |
| Dockerfile Compatibility | 100% | ~95% |
| Use Case | Development and testing | Production CI/CD |
DinD vs sysbox
sysbox: More secure container runtime
| Feature | DinD | sysbox |
|---|---|---|
| Security | Medium | High |
| Setup Complexity | Simple | Complex |
| Compatibility | High | Medium |
| Performance | Medium | Better |
Best Practices Summary
Development Environment
# Use dind mode + Podman
manyoyo run -m dind -r claude
# AI-assisted containerized application development
# Fast iteration, testing, debuggingCI/CD Environment
# Use automation scripts
manyoyo run -m dind -x "
podman build -t myapp:$CI_COMMIT_SHA . &&
podman run --rm myapp:$CI_COMMIT_SHA npm test
"Production Environment
DinD is not recommended, instead use:
- Dedicated container runtime (Kubernetes)
- Or use daemonless tools like Kaniko
Related Documentation
- Container Mode Comparison - Learn about different container modes
- Basic Usage - Learn basic commands
- Configuration Examples - View configuration examples
- Troubleshooting - Solve runtime issues