Docker for LLMs
Containerize Large Language Models for consistent, portable, and scalable deployments. Docker is the foundation for modern AI infrastructure, enabling teams to package, ship, and run LLMs anywhere.
What is Docker and Why Use It for LLMs?
Docker is a containerization platform that packages applications and all their dependencies into standardized units called containers. Think of a container as a lightweight, portable "box" that contains everything your LLM needs to run: the model code, Python libraries, CUDA drivers, and system configurations.
For LLM deployments, this solves a critical challenge: LLMs have complex dependencies. A typical LLM inference setup requires specific versions of PyTorch, HuggingFace Transformers, CUDA, cuDNN, and dozens of other libraries. Without Docker, getting these working across different machines often leads to frustrating "dependency hell" and the infamous "it works on my machine" problem.
With Docker, you define your environment once, and it runs identically everywhere—on your laptop, your colleague's workstation, staging servers, or production cloud infrastructure.
Key Advantages
Environment Consistency
Your LLM runs identically in development, testing, and production. No more "works on my machine" issues. Every team member uses the exact same environment.
Dependency Isolation
Each container has its own Python, CUDA, and libraries. Run multiple models with different requirements on the same server without conflicts.
Portability
Deploy the same Docker image to AWS, GCP, Azure, or on-premise. Switch cloud providers without rewriting deployment scripts.
Scalability
Scale horizontally by running multiple container instances. Docker Compose for local, Kubernetes for production orchestration at scale.
Faster Deployment
Pre-built images include all dependencies. Deployment reduces to a single `docker run` command. CI/CD pipelines become simpler and faster.
Security & Isolation
Containers run in isolation from the host system and each other. Limit resources, restrict network access, and enforce least-privilege security.
When Should You Use Docker for LLMs?
| Scenario | Use Docker? | Reason |
|---|---|---|
| Production deployment | Yes ✓ | Reproducible, scalable, easy rollbacks |
| Team collaboration | Yes ✓ | Everyone uses same environment |
| Multi-cloud deployment | Yes ✓ | Same image works everywhere |
| Running multiple models | Yes ✓ | Isolated dependencies per model |
| Quick local testing | Optional | Ollama native may be simpler |
| One-off experiments | Probably not | Overhead may not be worth it |
Setting Up GPU Access in Docker
By default, Docker containers cannot access the host's GPU. To run LLMs with GPU acceleration, you need to install the NVIDIA Container Toolkit. This allows Docker to pass through GPU resources to containers, enabling CUDA-based inference.
1. Install NVIDIA Container Toolkit (Ubuntu/Debian)
# Add NVIDIA package repository curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo 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' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list # Install the toolkit sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
2. Configure Docker to Use NVIDIA Runtime
# Configure Docker to recognize NVIDIA runtime sudo nvidia-ctk runtime configure --runtime=docker # Restart Docker to apply changes sudo systemctl restart docker
3. Verify GPU Access
# This should display your GPU info inside the container docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi
If you see your GPU listed, Docker is now configured for GPU-accelerated LLM inference!
Running Ollama in Docker
Ollama is the easiest way to run LLMs locally. The Docker image provides a ready-to-use server with GPU support. This is ideal for development, testing, or small-scale deployments.
# Start Ollama server with GPU support
docker run -d --gpus all \
-v ollama:/root/.ollama \
-p 11434:11434 \
--name ollama \
ollama/ollama
# Download and run a model (inside the container)
docker exec -it ollama ollama run llama3.1
# Or use the API directly
curl http://localhost:11434/api/generate -d '{
"model": "llama3.1",
"prompt": "Explain Docker in simple terms"
}'
💡 Why use a volume? The -v ollama:/root/.ollama flag creates a named
volume to persist downloaded models. Without this, models would be deleted when the container
restarts.
Running vLLM in Docker (Production)
vLLM is the industry-standard for high-throughput LLM inference. It uses PagedAttention to maximize GPU utilization and provides an OpenAI-compatible API. This is the recommended choice for production deployments.
# Run vLLM with OpenAI-compatible API
docker run -d --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 \
-e HUGGING_FACE_HUB_TOKEN=$HF_TOKEN \
--name vllm \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct \
--port 8000
# Test with curl (OpenAI-compatible API)
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"messages": [{"role": "user", "content": "Hello!"}]
}'
✓ Production-ready: vLLM in Docker is how many companies deploy LLMs at scale. The OpenAI-compatible API means you can use existing OpenAI SDKs with your self-hosted model.
Text Generation Inference (TGI)
TGI is HuggingFace's production inference server. It's optimized for HuggingFace models and includes features like quantization, flash attention, and tensor parallelism. Great if you're already in the HuggingFace ecosystem.
# Run TGI with a HuggingFace model docker run -d --gpus all \ -v ~/.cache/huggingface:/data \ -p 8080:80 \ -e MODEL_ID=meta-llama/Llama-3.1-8B-Instruct \ -e HUGGING_FACE_HUB_TOKEN=$HF_TOKEN \ --name tgi \ ghcr.io/huggingface/text-generation-inference:latest # With AWQ quantization (4-bit, uses less VRAM) docker run -d --gpus all \ -v ~/.cache/huggingface:/data \ -p 8080:80 \ -e MODEL_ID=TheBloke/Llama-2-7B-AWQ \ -e QUANTIZE=awq \ ghcr.io/huggingface/text-generation-inference:latest
Docker Compose for Production
Docker Compose defines your entire stack in a single file. It's easier to manage than
long docker run commands and enables features like health checks, automatic restarts, and
resource limits.
# docker-compose.yml
version: "3.8"
services:
vllm:
image: vllm/vllm-openai:latest
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
- huggingface-cache:/root/.cache/huggingface
ports:
- "8000:8000"
environment:
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}
command: >
--model meta-llama/Llama-3.1-8B-Instruct
--port 8000
--gpu-memory-utilization 0.9
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
huggingface-cache:
Start with:
docker compose up -d
Multi-GPU Configuration
For large models (30B+), you may need multiple GPUs. Docker supports selecting specific GPUs or using all available GPUs for tensor parallelism.
Use All GPUs
docker run --gpus all ...
Use Specific GPUs (by index)
# Use only GPU 0 and GPU 1 docker run --gpus '"device=0,1"' ...
vLLM Tensor Parallelism (70B model across 4 GPUs)
docker run --gpus all vllm/vllm-openai:latest \ --model meta-llama/Llama-3.1-70B-Instruct \ --tensor-parallel-size 4
Best Practices
Persist Model Cache
Mount ~/.cache/huggingface as a
volume. Models are large (5-40GB+)—avoid re-downloading them every time the container restarts.
Use Health Checks
Add health checks so Docker (or Kubernetes) can automatically restart crashed containers. LLMs can crash on OOM errors.
Secure API Tokens
Use environment variables or Docker secrets for HuggingFace tokens. Never hardcode secrets in Dockerfiles or compose files.
Increase Shared Memory
Use --shm-size=1g or higher for
large models. PyTorch uses shared memory for data loading, and the default 64MB is often
insufficient.