The NVIDIA Dynamo project uses containerized development and deployment to maintain consistent environments across different AI inference frameworks and deployment scenarios. This directory contains the tools for building and running Dynamo containers:
-
build.sh- A Docker image builder that creates containers for different AI inference frameworks (vLLM, TensorRT-LLM, SGLang). It handles framework-specific dependencies, multi-stage builds, and development vs production configurations. -
run.sh- A container runtime manager that launches Docker containers with proper GPU access, volume mounts, and environment configurations. It supports different development workflows from root-based legacy setups to user-based development environments. -
Multiple Dockerfiles - Framework-specific Dockerfiles that define the container images:
Dockerfile.vllm- For vLLM inference backendDockerfile.trtllm- For TensorRT-LLM inference backendDockerfile.sglang- For SGLang inference backendDockerfile- Base/standalone configuration
Each inference framework (vLLM, TensorRT-LLM, SGLang) has specific CUDA versions, Python dependencies, and system libraries. Containers provide consistent environments, framework isolation, and proper GPU configurations across development and production.
The scripts in this directory abstract away the complexity of Docker commands while providing fine-grained control over build and runtime configurations.
The build.sh and run.sh scripts are convenience wrappers that simplify common Docker operations. They automatically handle:
- Framework-specific image selection and tagging
- GPU access configuration and runtime selection
- Volume mount setup for development workflows
- Environment variable management
- Build argument construction for multi-stage builds
You can always use Docker commands directly if you prefer more control or want to customize beyond what the scripts provide. The scripts use --dry-run flags to show you the exact Docker commands they would execute, making it easy to understand and modify the underlying operations.
These targets are specified with build.sh --target <target> and correspond to Docker multi-stage build targets defined in the Dockerfiles (e.g., FROM somebase AS <target>). Some commonly used targets include:
runtime- For running pre-built containers without development tools (minimal size)dev- For development (inferencing/benchmarking/etc, runs as root user)local-dev- For development with local user permissions matching host UID/GID. This is useful when mounting host partitions (with local user permissions) to Docker partitions.
Additional targets are available in the Dockerfiles for specific build stages and use cases.
Feature │ 1. dev + `run.sh` │ 2. local-dev + `run.sh` │ 3. local-dev + Dev Container
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Default User │ root │ ubuntu │ ubuntu
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
User Setup │ None │ Matches UID/GID of │ Matches UID/GID of
│ │ `build.sh` user │ `build.sh` user
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Permissions │ root │ ubuntu with sudo │ ubuntu with sudo
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Home Directory │ /root │ /home/ubuntu │ /home/ubuntu
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Working Directory │ /workspace │ /workspace │ /home/ubuntu/dynamo
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Rust Toolchain │ System install │ User install (~/.rustup, │ User install (~/.rustup,
│ (/usr/local/rustup, │ ~/.cargo) │ ~/.cargo)
│ /usr/local/cargo) │ │
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Python Env │ root owned │ User owned venv │ User owned venv
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
File Permissions │ root-level │ user-level, safe │ user-level, safe
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
Compatibility │ Legacy workflows, │ workspace writable on NFS│workspace writable on NFS
│ workspace not │ │
│ writable on NFS │ │
──────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────
- Use dev +
run.sh: for command-line testing. Runs as root user - Use local-dev +
run.sh: for command-line development and Docker mounted partitions using your local user ID - Use local-dev + Dev Container: VS Code/Cursor Dev Container Plugin, using your local user ID
run.sh ...run.sh --mount-workspace --image dynamo:latest-vllm-local-dev ...Use VS Code/Cursor Dev Container Extension with devcontainer.json configuration
The build.sh script is responsible for building Docker images for different AI inference frameworks. It supports multiple frameworks and configurations:
Purpose:
- Builds Docker images for NVIDIA Dynamo with support for vLLM, TensorRT-LLM, SGLang, or standalone configurations
- Handles framework-specific dependencies and optimizations
- Manages build contexts, caching, and multi-stage builds
- Configures development vs production targets
Key Features:
- Framework Support: vLLM (default when --framework not specified), TensorRT-LLM, SGLang, or NONE
- Multi-stage Builds: Build process with base images
- Development Targets: Supports
devtarget andlocal-devtarget - Build Caching: Docker layer caching and sccache support
- GPU Optimization: CUDA, EFA, and NIXL support
Common Usage Examples:
# Build vLLM dev image called dynamo:latest-vllm (default). This runs as root and is fine to use for inferencing/benchmarking, etc.
./build.sh
# Build both development and local-dev images (integrated into build.sh). While the dev image runs as root, the local-dev image will run as the local user, which is useful when mounting partitions. It will also contain development tools.
./build.sh --framework vllm --target local-dev
# Build TensorRT-LLM development image called dynamo:latest-trtllm
./build.sh --framework trtllm
# Build with custom tag
./build.sh --framework sglang --tag my-custom-tag
# Dry run to see commands
./build.sh --dry-run
# Build with no cache
./build.sh --no-cache
# Build with build arguments
./build.sh --build-arg CUSTOM_ARG=valueThe build.sh --dev-image option takes a dev image and then builds a local-dev image, which contains proper local user permissions. It also includes extra developer utilities (debugging tools, text editors, system monitors, etc.).
Common Usage Examples:
# Build local-dev image from dev image dynamo:latest-vllm
./build.sh --dev-image dynamo:latest-vllm --framework vllm
# Build with custom tag from dev image dynamo:latest-vllm
./build.sh --dev-image dynamo:latest-vllm --framework vllm --tag my-local:dev
# Dry run to see what would be built
./build.sh --dev-image dynamo:latest-vllm --framework vllm --dry-runThe run.sh script launches Docker containers with the appropriate configuration for development and inference workloads.
Purpose:
- Runs pre-built Dynamo Docker images with proper GPU access
- Configures volume mounts, networking, and environment variables
- Supports different development workflows (root vs user-based)
- Manages container lifecycle and resource allocation
Key Features:
- GPU Management: Automatic GPU detection and allocation
- Volume Mounting: Workspace and HuggingFace cache mounting
- User Management: Root or user-based container execution
- Network Configuration: Configurable networking modes (host, bridge, none, container sharing)
- Resource Limits: Memory, file descriptors, and IPC configuration
Common Usage Examples:
# Basic container launch (inference/production, runs as root user)
./run.sh --image dynamo:latest-vllm -v $HOME/.cache:/home/ubuntu/.cache
# Mount workspace for development (use local-dev image for local host user permissions)
./run.sh --image dynamo:latest-vllm-local-dev --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache
# Use specific image and framework for development
./run.sh --image v0.1.0.dev.08cc44965-vllm-local-dev --framework vllm --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache
# Interactive development shell with workspace mounted
./run.sh --image dynamo:latest-vllm-local-dev --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache -it -- bash
# Development with custom environment variables
./run.sh --image dynamo:latest-vllm-local-dev -e CUDA_VISIBLE_DEVICES=0,1 --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache
# Dry run to see docker command
./run.sh --dry-run
# Development with custom volume mounts
./run.sh --image dynamo:latest-vllm-local-dev -v /host/path:/container/path --mount-workspace -v $HOME/.cache:/home/ubuntu/.cacheThe run.sh script supports different networking modes via the --network flag (defaults to host):
# Same examples with local host user permissions
./run.sh --image dynamo:latest-vllm-local-dev --network host -v $HOME/.cache:/home/ubuntu/.cache
./run.sh --image dynamo:latest-vllm-local-dev -v $HOME/.cache:/home/ubuntu/.cacheUse cases:
- High-performance ML inference (default for GPU workloads)
- Services that need direct host port access
- Maximum network performance with minimal overhead
- Sharing services with the host machine (NATS, etcd, etc.)
# CI/testing with isolated bridge networking and host cache sharing
./run.sh --image dynamo:latest-vllm --mount-workspace --network bridge -v $HOME/.cache:/home/ubuntu/.cacheUse cases:
- Secure isolation from host network
- CI/CD pipelines requiring complete isolation
- When you need absolute control of ports
- Exposing specific services to host while maintaining isolation
Note: For port sharing with the host, use the --port or -p option with format host_port:container_port (e.g., --port 8000:8000 or -p 9081:8081) to expose specific container ports to the host.
# Complete network isolation - no external connectivity
./run.sh --image dynamo:latest-vllm --network none --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache
# Same with local user permissions
./run.sh --image dynamo:latest-vllm-local-dev --network none --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache--network none severely limits Dynamo functionality:
- No model downloads - HuggingFace models cannot be downloaded
- No API access - Cannot reach external APIs or services
- No distributed inference - Multi-node setups won't work
- No monitoring/logging - External monitoring systems unreachable
- Limited debugging - Cannot access external debugging tools
Very limited use cases:
- Pre-downloaded models with purely local processing
- Air-gapped security environments (models must be pre-staged)
Use --network container:name to share the network namespace with another container.
Use cases:
- Sidecar patterns (logging, monitoring, caching)
- Service mesh architectures
- Sharing network namespaces between related containers
See Docker documentation for --network container:name usage.
Use custom Docker networks for multi-container applications. Create with docker network create and specify with --network network-name.
Use cases:
- Multi-container applications
- Service discovery by container name
See Docker documentation for custom network creation and management.
| Mode | Performance | Security | Use Case | Dynamo Compatibility | Port Sharing | Port Publishing |
|---|---|---|---|---|---|---|
host |
Highest | Lower | ML/GPU workloads, high-performance services | ✅ Full | ❌ Not needed | |
bridge |
Good | Higher | General web services, controlled port exposure | ✅ Full | ✅ Isolated ports | ✅ -p host:container |
none |
N/A | Highest | Air-gapped environments only | ✅ No network | ❌ No network | |
container:name |
Good | Medium | Sidecar patterns, shared network stacks | ✅ Full | ❌ Use target's ports | |
| Custom networks | Good | Medium | Multi-container applications | ✅ Full | ✅ Isolated ports | ✅ -p host:container |
# 1. Build local-dev image (creates both dynamo:latest-vllm and dynamo:latest-vllm-local-dev)
./build.sh --framework vllm --target local-dev
# 2. Run development container using the local-dev image
./run.sh --image dynamo:latest-vllm-local-dev --mount-workspace -v $HOME/.cache:/home/ubuntu/.cache -it
# 3. Inside container, run inference (requires both frontend and backend)
# Start frontend
python -m dynamo.frontend &
# Start backend (vLLM example)
python -m dynamo.vllm --model Qwen/Qwen3-0.6B --gpu-memory-utilization 0.20 &# 1. Build production image
./build.sh --framework vllm --release-build
# 2. Run production container (runs as root)
./run.sh --image dynamo:latest-vllm --gpus all# 1. Build image for CI
./build.sh --framework vllm --no-cache
# 2. Run tests with network isolation for reproducible results
./run.sh --image dynamo:latest-vllm --mount-workspace --network bridge -v $HOME/.cache:/home/ubuntu/.cache -- python -m pytest tests/
# 3. Inside the container with bridge networking, start services
# Note: Services are only accessible from the same container - no port conflicts with host
nats-server -js &
etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379 --data-dir /tmp/etcd &
python -m dynamo.frontend &
# 4. Start worker backend (choose one framework):
# vLLM
DYN_SYSTEM_ENABLED=true DYN_SYSTEM_PORT=8081 python -m dynamo.vllm --model Qwen/Qwen3-0.6B --gpu-memory-utilization 0.20 --enforce-eager --no-enable-prefix-caching --max-num-seqs 64 &
# SGLang
DYN_SYSTEM_ENABLED=true DYN_SYSTEM_PORT=8081 python -m dynamo.sglang --model Qwen/Qwen3-0.6B --mem-fraction-static 0.20 --max-running-requests 64 &
# TensorRT-LLM
DYN_SYSTEM_ENABLED=true DYN_SYSTEM_PORT=8081 python -m dynamo.trtllm --model Qwen/Qwen3-0.6B --free-gpu-memory-fraction 0.20 --max-num-tokens 8192 --max-batch-size 64 &Framework-Specific GPU Memory Arguments:
- vLLM:
--gpu-memory-utilization 0.20(use 20% GPU memory),--enforce-eager(disable CUDA graphs),--no-enable-prefix-caching(save memory),--max-num-seqs 64(max concurrent sequences) - SGLang:
--mem-fraction-static 0.20(20% GPU memory for static allocation),--max-running-requests 64(max concurrent requests) - TensorRT-LLM:
--free-gpu-memory-fraction 0.20(reserve 20% GPU memory),--max-num-tokens 8192(max tokens in batch),--max-batch-size 64(max batch size)