Docker eliminates “it works on my machine” forever. By packaging your code, dependencies, and environment into a container, Docker guarantees your ML model runs identically on your laptop, your teammate’s machine, and production servers. This guide gets data scientists productive with Docker from first principles.
Why Docker for Data Science?
Python dependency conflicts are the bane of data science teams. Project A needs TensorFlow 2.12, Project B needs 2.15; NumPy version conflicts break scikit-learn; CUDA versions must match PyTorch versions exactly. Docker solves all of this by isolating each project in its own container with its own Python environment, OS libraries, and GPU drivers. The container is self-contained and reproducible — share a Dockerfile and anyone can recreate your exact environment in minutes.
Docker Concepts in 2 Minutes
An image is a read-only blueprint (like a class in OOP). A container is a running instance of an image (like an object). A Dockerfile is the recipe for building an image. Docker Hub is the public registry of pre-built images. The Docker daemon is the background service that manages images and containers.
Your First Dockerfile
# Dockerfile
FROM python:3.11-slim # start from official Python image
WORKDIR /app # set working directory inside container
# Copy and install requirements first (leverages build cache)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy your project files
COPY . .
# Expose port and set startup command
EXPOSE 8000
CMD ["python", "train.py"]
# Build the image
docker build -t my-ml-project:v1 .
# Run a container from it
docker run my-ml-project:v1
# Run interactively (to debug)
docker run -it my-ml-project:v1 bash
Dockerizing a Jupyter Notebook Server
# Dockerfile.jupyter
FROM jupyter/scipy-notebook:latest
USER root
RUN pip install --no-cache-dir xgboost lightgbm shap
USER $NB_UID
WORKDIR /home/$NB_USER/work
# Run Jupyter with your local notebooks mounted
docker run -p 8888:8888 -v $(pwd)/notebooks:/home/jovyan/work my-jupyter
# Access at http://localhost:8888
Dockerizing a FastAPI ML Model
# requirements.txt
fastapi==0.111.0
uvicorn==0.30.0
scikit-learn==1.4.2
pandas==2.2.2
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY model.pkl .
COPY app.py .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
# Build and run
docker build -t fraud-api:latest .
docker run -p 8000:8000 fraud-api:latest
# Test
curl -X POST http://localhost:8000/predict -H "Content-Type: application/json" -d '{"amount": 5000, "hour": 3, "merchant_category": "online"}'
Docker Compose – Multi-Container Setups
# docker-compose.yml
version: "3.9"
services:
api:
build: .
ports:
- "8000:8000"
environment:
- MODEL_PATH=/models/fraud_model.pkl
volumes:
- ./models:/models
depends_on:
- redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
mlflow:
image: ghcr.io/mlflow/mlflow:v2.13.0
ports:
- "5000:5000"
command: mlflow server --host 0.0.0.0
volumes:
- ./mlruns:/mlruns
docker compose up # start all services
docker compose up -d # detached (background)
docker compose down # stop and remove
docker compose logs api # view logs for one service
Useful Docker Commands for Daily Use
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# View logs
docker logs -f container_name
# Execute a command in a running container
docker exec -it container_name bash
# Copy files between host and container
docker cp container_name:/app/output.csv ./output.csv
# Remove all stopped containers and unused images (free disk space)
docker system prune -f
# View image sizes
docker images
Mounting Volumes for Persistent Data
# Mount a local directory for data persistence
docker run -v /local/data:/app/data my-ml-project
# Named volume (managed by Docker, survives container deletion)
docker run -v ml_data:/app/data my-ml-project
docker volume ls
GPU Support with NVIDIA Docker
# Install nvidia-container-toolkit first
# Then run with GPU access
docker run --gpus all nvcr.io/nvidia/pytorch:24.04-py3 python -c "import torch; print(torch.cuda.is_available())"
# In docker-compose.yml
services:
trainer:
image: my-trainer
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Conclusion
Docker is non-negotiable for serious data science work in 2026. It makes your models reproducible, your APIs deployable, and your environments shareable. The learning curve is a few hours; the payoff is never debugging a dependency conflict again. Start with a simple Dockerfile for your current project, then graduate to Docker Compose when you need multiple services running together.



