0% found this document useful (0 votes)
5 views25 pages

Docker Coding

The document serves as a comprehensive Docker coding reference tailored for AI engineers, detailing essential commands, flags, and practical examples for container management, image building, and Dockerfile instructions. It covers commands for running containers, managing images, and configuring networks and volumes, alongside real-world examples for AI model deployment. Additionally, it explains Dockerfile patterns, including base images, command execution, and best practices for copying files and managing variables.

Uploaded by

aryan.patel25jan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views25 pages

Docker Coding

The document serves as a comprehensive Docker coding reference tailored for AI engineers, detailing essential commands, flags, and practical examples for container management, image building, and Dockerfile instructions. It covers commands for running containers, managing images, and configuring networks and volumes, alongside real-world examples for AI model deployment. Additionally, it explains Dockerfile patterns, including base images, command execution, and best practices for copying files and managing variables.

Uploaded by

aryan.patel25jan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Docker Coding Reference — AI Engineers Edition

⌨️
DOCKER
Complete Coding Reference
Every Command, Every Flag, Real AI/ML Code — Fully Explained

DOCUMENT 2 OF 2 — CODE

Page 1 of 25
Docker Coding Reference — AI Engineers Edition

Section 1: Essential Docker Commands — Every Flag


Explained
1.1 docker run — The Most Important Command
docker run creates a container from an image and starts it. It is shorthand for docker create +
docker start combined. It has dozens of flags — here are all the important ones:

# Full syntax:
docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]

# ── Identity & Naming ───────────────────────────────────────────


--name my-container # Give it a human-readable name (else random)
--hostname ml-server # Set container's hostname inside

# ── Detached / Interactive ─────────────────────────────────────


-d # Detached mode: run in background, print container ID
-it # Interactive + pseudo-TTY: for shell access
--rm # Auto-remove container when it exits (great for tests)

# ── Port Mapping ───────────────────────────────────────────────


-p 8080:8000 # Host port 8080 → container port 8000
-p [Link]:8080:8000 # Bind to localhost only (more secure)
-P # Publish ALL exposed ports to random host ports

# ── Volume Mounts ──────────────────────────────────────────────


-v myvolume:/app/data # Named volume mount
-v $(pwd)/src:/app/src # Bind mount (current dir/src → /app/src)
-v /data/models:/models:ro # Read-only bind mount (:ro flag)
--tmpfs /tmp # RAM-backed temporary filesystem (lost on stop)

# ── Environment Variables ─────────────────────────────────────


-e MY_VAR=value # Set single environment variable
--env-file .env # Load all vars from a .env file

# ── Resource Limits ─────────────────────────────────────────


--memory=8g # Hard RAM limit (container killed if exceeded)
--memory-swap=16g # Total memory+swap limit
--cpus=4 # Limit to 4 CPU cores (can be fractional: 0.5)
--cpu-shares=512 # Relative CPU weight (default 1024)

# ── GPU Access ───────────────────────────────────────────────


--gpus all # All GPUs
--gpus 1 # One GPU
--gpus "device=0,1" # Specific GPU IDs

# ── Network ─────────────────────────────────────────────────
--network mynet # Attach to user-defined network
--network host # Share host network stack (no isolation)
--network none # No network at all
--add-host=mydb:[Link] # Add entry to /etc/hosts
--dns=[Link] # Custom DNS server

Page 2 of 25
Docker Coding Reference — AI Engineers Edition

# ── Security ────────────────────────────────────────────────
--user 1001:1001 # Run as UID:GID (non-root)
--read-only # Mount root filesystem as read-only
--cap-drop=ALL # Drop all Linux capabilities
--cap-add=NET_BIND_SERVICE # Add back only what's needed
--security-opt=no-new-privileges # Prevent privilege escalation

# ── Restart Policy ──────────────────────────────────────────


--restart=no # Never restart (default)
--restart=always # Always restart (even on docker daemon restart)
--restart=unless-stopped # Always restart unless manually stopped
--restart=on-failure:3 # Restart on non-zero exit, max 3 times

# ── Real-world AI model server example:


docker run -d \
--name model-api \
--gpus all \
--memory=16g \
--cpus=8 \
-p [Link]:8000:8000 \
-v model-weights:/app/models \
-e MODEL_NAME=llama-3-8b \
--env-file .[Link] \
--restart=unless-stopped \
--network ai-stack \
my-model-api:v1.2.3

1.2 docker build — Building Images


docker build reads a Dockerfile and creates an image. Every flag matters for production builds:

# Basic build (. = build context is current directory):


docker build -t myimage:v1.0 .

# Full syntax:
docker build [OPTIONS] PATH | URL | -

# ── Tagging ─────────────────────────────────────────────────
-t myimage:latest # Name and tag the output image
-t myimage:v1.0 -t myimage:latest # Multiple tags at once

# ── Dockerfile location ─────────────────────────────────────


-f ./docker/[Link] # Use specific Dockerfile (default: ./Dockerfile)

# ── Multi-stage builds ──────────────────────────────────────


--target builder # Stop at 'builder' stage (don't build final)

# ── Build arguments ─────────────────────────────────────────


--build-arg PYTHON_VER=3.11 # Pass ARG values (defined in Dockerfile)
--build-arg MODEL_URL=[Link]

# ── Cache control ───────────────────────────────────────────

Page 3 of 25
Docker Coding Reference — AI Engineers Edition

--no-cache # Ignore all cached layers (full rebuild)


--cache-from myimage:latest # Use a remote image as cache source (CI/CD)

# ── Platform / Architecture ─────────────────────────────────


--platform linux/amd64 # Build for x86 (default on most machines)
--platform linux/arm64 # Build for ARM (Apple M-series, Graviton)
--platform linux/amd64,linux/arm64 # Multi-arch (with buildx)

# ── Output ─────────────────────────────────────────────────
--push # Push directly to registry after build
--load # Load into local Docker (with buildx)
--squash # Squash all layers into one (loses cache)

# ── Progress ────────────────────────────────────────────────
--progress=plain # Show full build output (good for debugging)
--progress=auto # Default: condensed output

# CI/CD production build example:


docker build \
-t myrepo/model-api:${GIT_SHA} \
-t myrepo/model-api:latest \
-f [Link] \
--build-arg PYTHON_VERSION=3.11.9 \
--cache-from myrepo/model-api:latest \
--platform linux/amd64 \
--push \
.

1.3 Container Management Commands


# ── Listing ─────────────────────────────────────────────────
docker ps # Running containers
docker ps -a # ALL containers (including stopped)
docker ps --format 'table {{.Names}} {{.Status}} {{.Ports}}'

# ── Starting / Stopping ─────────────────────────────────────


docker start mycontainer # Start a stopped container
docker stop mycontainer # Send SIGTERM, wait 10s, then SIGKILL
docker stop -t 30 mycontainer # Wait 30s before SIGKILL (for slow cleanup)
docker kill mycontainer # SIGKILL immediately (no graceful shutdown)
docker restart mycontainer # Stop + Start
docker pause mycontainer # Freeze (SIGSTOP all processes)
docker unpause mycontainer # Unfreeze

# ── Removal ─────────────────────────────────────────────────
docker rm mycontainer # Remove stopped container
docker rm -f mycontainer # Force remove (even if running)
docker rm $(docker ps -aq) # Remove ALL stopped containers

# ── Inspection / Debugging ──────────────────────────────────


docker logs mycontainer # Show stdout/stderr from container
docker logs -f mycontainer # Follow (stream) logs in real time
docker logs --tail=100 mycontainer # Last 100 lines

Page 4 of 25
Docker Coding Reference — AI Engineers Edition

docker logs --since=1h mycontainer # Logs from last 1 hour

docker exec -it mycontainer bash # Open shell INSIDE running container
docker exec mycontainer python -c 'import torch; print(torch.__version__)'
docker exec -u root mycontainer bash # Enter as root even if USER is set

docker inspect mycontainer # Full JSON metadata (IPs, mounts, config)


docker inspect mycontainer | python -m [Link] # Pretty-print
docker inspect -f '{{.[Link]}}' mycontainer

docker stats # Live CPU/RAM/NET/IO for all running containers


docker stats --no-stream # One-time snapshot (good for scripts)
docker top mycontainer # Processes running inside container
docker port mycontainer # Port mappings
docker diff mycontainer # Files changed in container layer

# ── Copying files ────────────────────────────────────────────


docker cp mycontainer:/app/[Link] ./[Link] # Container→Host
docker cp ./[Link] mycontainer:/app/[Link] # Host→Container

1.4 Image Management Commands


# ── Listing & Searching ─────────────────────────────────────
docker images # List local images
docker images -a # Include intermediate layers
docker image ls --filter dangling=true # Untagged leftover images
docker search pytorch # Search Docker Hub

# ── Pulling & Pushing ───────────────────────────────────────


docker pull python:3.11-slim # Pull specific tag
docker pull python@sha256:abc123... # Pull by digest (reproducible)
docker push myrepo/myimage:v1.0 # Push to registry

# ── Tagging ─────────────────────────────────────────────────
docker tag myimage:v1 myrepo/myimage:v1 # Add tag to existing image
docker tag myimage:v1 myrepo/myimage:latest

# ── Inspection ──────────────────────────────────────────────
docker inspect python:3.11-slim # Full image metadata
docker history myimage:v1 # Show all layers and their sizes
docker image inspect -f '{{.[Link]}}' python:3.11 # View ENVs

# ── Removal & Cleanup ───────────────────────────────────────


docker rmi myimage:v1 # Remove image
docker rmi -f myimage:v1 # Force remove (even if tagged)
docker image prune # Remove dangling (untagged) images
docker image prune -a # Remove ALL unused images
docker system prune # Remove stopped
containers+networks+dangling images
docker system prune -a --volumes # Nuclear option: clean EVERYTHING
docker system df # Show disk usage breakdown

# ── Registry Login ──────────────────────────────────────────

Page 5 of 25
Docker Coding Reference — AI Engineers Edition

docker login # Login to Docker Hub


docker login [Link] # Login to GitHub Container Registry
docker login -u AWS -p $(aws ecr get-login-password) [Link]-east-
[Link]

# ── Save/Load (for offline transfer) ───────────────────────


docker save myimage:v1 > [Link] # Export to tar file
docker load < [Link] # Import from tar file
docker export mycontainer > [Link] # Export container fs
docker import [Link] newimage:v1 # Import as image

1.5 Network & Volume Commands


# ── Networks ────────────────────────────────────────────────
docker network ls # List all networks
docker network create mynet # Create bridge network
docker network create --driver overlay myswarmnet # Overlay for Swarm
docker network create --subnet=[Link]/16 --gateway=[Link] mynet
docker network inspect mynet # Full network details
docker network connect mynet mycontainer # Add running container to network
docker network disconnect mynet mycontainer # Remove from network
docker network rm mynet # Delete network
docker network prune # Remove all unused networks

# ── Volumes ─────────────────────────────────────────────────
docker volume ls # List volumes
docker volume create model-weights # Create named volume
docker volume inspect model-weights # Details (mount path, driver)
docker volume rm model-weights # Delete volume
docker volume prune # Delete unused volumes

# Backup a volume:
docker run --rm -v model-weights:/data -v $(pwd):/backup \
ubuntu tar czf /backup/[Link] /data

# Restore a volume:
docker run --rm -v model-weights:/data -v $(pwd):/backup \
ubuntu tar xzf /backup/[Link] -C /

Page 6 of 25
Docker Coding Reference — AI Engineers Edition

Section 2: Dockerfiles — Every Pattern Explained


2.1 Complete Dockerfile Instruction Reference with Examples
FROM — The Base Image
# Single base:
FROM python:3.11-slim

# Multi-stage — name each stage:


FROM python:3.11-slim AS builder
FROM python:3.11-slim AS runtime

# Specific digest (pinned, never changes — production must-have):


FROM python:3.11-
slim@sha256:4c2cf627f2606b5e6f7c6b9b3e82b6d06e882c6fbf05f10f5b3cc4a4c3c8e4b2

# Cross-platform build:
FROM --platform=linux/amd64 python:3.11-slim

# Use ARG before FROM for dynamic base versions:


ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION}-slim
# Note: ARG before FROM is not available after FROM — redefine if needed

RUN — Execute Commands


# Shell form (uses /bin/sh -c):
RUN pip install torch

# Exec form (no shell — more explicit, needed for args with spaces):
RUN ["pip", "install", "torch"]

# CORRECT: Chain commands to minimize layers and clean up in SAME layer:


RUN apt-get update && \
apt-get install -y --no-install-recommends \
libgomp1 \
curl \
git && \
rm -rf /var/lib/apt/lists/*
# Why rm at end? apt cache is ~100MB. If you rm in a SEPARATE RUN, it stays
# in the previous layer. Same RUN = removed from that layer too.

# BuildKit cache mounts — persistent cache between builds (huge speedup):


# syntax=docker/dockerfile:1.5 ← Must be first line of Dockerfile
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r [Link]
# This keeps pip's download cache across builds — first build downloads,
# subsequent builds just install from cache. Huge for large packages.

# Secret mount — inject secrets without baking them into layers:


RUN --mount=type=secret,id=hf_token \

Page 7 of 25
Docker Coding Reference — AI Engineers Edition

HF_TOKEN=$(cat /run/secrets/hf_token) \
python download_model.py
# Build: docker build --secret id=hf_token,src=./hf_token.txt .

COPY vs ADD
# COPY: Prefer this always. Simple, predictable.
COPY [Link] /app/[Link]
COPY --chown=appuser:appuser ./src /app/src # Set ownership
COPY --chmod=755 [Link] /[Link] # Set permissions

# COPY from another build stage (multi-stage):


COPY --from=builder /install /usr/local
COPY --from=builder /app/[Link] /app/[Link]

# ADD: Only use when you need auto-extraction or URL download.


ADD [Link] /app/models/ # Auto-extracts tarball
# WARNING: ADD from URL is not recommended — use RUN curl/wget instead
# (ADD URL not cached, curl gives you more control)

ENV and ARG — Variables


# ARG: Build-time only. NOT in final image. Use for versions, paths.
ARG MODEL_VERSION=1.0
ARG HF_TOKEN # No default — must be passed via --build-arg

# ENV: Persists in final image. Visible at runtime and in docker inspect.


ENV PYTHONUNBUFFERED=1 # Disable Python output buffering (CRITICAL)
ENV PYTHONDONTWRITEBYTECODE=1 # Don't create .pyc files in container
ENV PYTHONPATH=/app/src # Python module search path
ENV MODEL_PATH=/app/models/[Link]
ENV PORT=8000

# Use ARG to set ENV (ARG visible at build time, ENV at runtime):
ARG APP_VERSION=unknown
ENV APP_VERSION=${APP_VERSION} # Now visible at runtime too

# Multiple ENVs in one instruction (best practice — fewer layers):


ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1

# NEVER put secrets in ENV or ARG — they appear in 'docker history':


# BAD: ENV OPENAI_API_KEY=sk-abc123
# GOOD: Pass at runtime: docker run -e OPENAI_API_KEY=$OPENAI_API_KEY ...

WORKDIR, USER, EXPOSE, VOLUME


# WORKDIR: Sets working directory. Creates it if not exists.
WORKDIR /app
# All subsequent RUN, COPY, CMD, ENTRYPOINT are relative to /app

Page 8 of 25
Docker Coding Reference — AI Engineers Edition

# Equivalent to: RUN mkdir -p /app && cd /app (but better)

# USER: Switch user for security. All subsequent instructions + container runtime.
RUN useradd --no-create-home --uid 1001 --shell /bin/false appuser
USER appuser
# After USER, RUN commands execute as appuser, not root
# Need to install packages? Put USER before COPY of your code, after installs.

# EXPOSE: DOCUMENTS that the container listens on this port.


# Does NOT publish it. Does NOT create firewall rules.
EXPOSE 8000
EXPOSE 8000/tcp 8001/udp # Protocol can be specified
# To actually publish: docker run -p 8080:8000 (host:container)

# VOLUME: Declares mount points for external data.


VOLUME /app/models # Model weights — expect to be mounted
VOLUME /app/logs # Logs — persist outside container
VOLUME ["/app/data", "/app/cache"] # Multiple volumes, exec form
# If no volume is mounted at runtime, Docker creates an anonymous volume.

ENTRYPOINT and CMD — The Process That Runs


# Three patterns:

# Pattern 1: CMD only (no ENTRYPOINT)


# Entire command in CMD. Fully overridable at runtime.
CMD ["python", "[Link]"]
# docker run myimage python different_script.py → overrides CMD completely

# Pattern 2: ENTRYPOINT only


# Fixed executable. Extra args appended to it.
ENTRYPOINT ["gunicorn"]
# docker run myimage -w 4 app:app → gunicorn -w 4 app:app

# Pattern 3: ENTRYPOINT + CMD (BEST for AI model servers)


# ENTRYPOINT = fixed program. CMD = default arguments.
ENTRYPOINT ["python", "-m", "uvicorn"]
CMD ["[Link]:app", "--host", "[Link]", "--port", "8000", "--workers", "2"]

# Override just the args:


# docker run myimage [Link]:app --port 9000 --workers 8
# Override entrypoint entirely:
# docker run --entrypoint bash myimage

# ALWAYS use exec form (JSON array) NOT shell form:


# BAD: CMD python [Link] → PID 1 is /bin/sh, python is a child
# GOOD: CMD ["python", "[Link]"] → python is PID 1, receives signals

# With tini (init process for signal handling + zombie reaping):


RUN apt-get install -y tini
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["python", "[Link]"]

Page 9 of 25
Docker Coding Reference — AI Engineers Edition

HEALTHCHECK and LABEL


# HEALTHCHECK: Docker periodically runs this to check container health.
HEALTHCHECK --interval=30s \ # Check every 30 seconds
--timeout=10s \ # Mark unhealthy if takes >10s
--start-period=60s \ # Grace period for startup (model loading)
--retries=3 \ # Fail 3 times in a row → unhealthy
CMD curl -f [Link] || exit 1

# For gRPC services:


HEALTHCHECK CMD grpc_health_probe -addr=:50051 || exit 1

# Disable inherited healthcheck:


HEALTHCHECK NONE

# LABEL: Add metadata. OCI-standard labels.


LABEL [Link]="My Model API"
LABEL [Link]="1.0.0"
LABEL [Link]="[Link]
LABEL [Link]="2024-01-15T12:00:00Z"
LABEL maintainer="ml-team@[Link]"
LABEL model="llama-3-8b"
LABEL framework="pytorch"
# Labels are queryable: docker inspect -f '{{.[Link]}}' myimage

Page 10 of 25
Docker Coding Reference — AI Engineers Edition

2.2 Complete Production Dockerfiles for AI Engineers


Dockerfile A: FastAPI Model Inference Server
# syntax=docker/dockerfile:1.5
# ═══════════════════════════════════════════════════════════
# Stage 1: Builder — install deps, don't carry build tools forward
# ═══════════════════════════════════════════════════════════
FROM python:3.11-slim AS builder

WORKDIR /build

# Install build tools (not in final image)


RUN apt-get update && apt-get install -y --no-install-recommends \
gcc g++ && \
rm -rf /var/lib/apt/lists/*

# Copy requirements FIRST — cache this layer (changes rarely)


COPY [Link] .

# Install to /install prefix — easy to copy to final stage


RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir --prefix=/install -r [Link]

# ═══════════════════════════════════════════════════════════
# Stage 2: Runtime — lean, secure final image
# ═══════════════════════════════════════════════════════════
FROM python:3.11-slim AS runtime

# Only runtime system deps


RUN apt-get update && apt-get install -y --no-install-recommends \
libgomp1 \ # OpenMP (required by many ML libs)
curl \ # For healthcheck
tini && \ # Init process
rm -rf /var/lib/apt/lists/*

# Copy installed Python packages from builder


COPY --from=builder /install /usr/local

WORKDIR /app

# Create non-root user


RUN useradd --no-create-home --uid 1001 --shell /bin/false appuser && \
mkdir -p /app/models /app/logs && \
chown -R appuser:appuser /app

# Critical environment variables


ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONPATH=/app/src \
MODEL_PATH=/app/models \
PORT=8000

# Copy application code last (changes most frequently — cache hit above)

Page 11 of 25
Docker Coding Reference — AI Engineers Edition

COPY --chown=appuser:appuser ./src /app/src


COPY --chown=appuser:appuser ./config /app/config

# Switch to non-root user


USER appuser

# Document which ports are used


EXPOSE 8000

# Document that models should be mounted here


VOLUME /app/models

# Metadata
LABEL [Link]="FastAPI Model Server"
LABEL maintainer="ml-team@[Link]"

# Health check (start-period covers model loading time)


HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
CMD curl -f [Link] || exit 1

# tini as init (signal handling + zombie reaping)


ENTRYPOINT ["/usr/bin/tini", "--"]
# CMD provides defaults — overridable at runtime
CMD ["python", "-m", "uvicorn", "[Link]:app",
"--host", "[Link]", "--port", "8000", "--workers", "2"]

Dockerfile B: PyTorch GPU Inference (CUDA)


# syntax=docker/dockerfile:1.5
ARG CUDA_VERSION=12.1.0
ARG UBUNTU_VERSION=22.04

# NVIDIA CUDA base image — includes CUDA runtime + cuDNN


FROM nvidia/cuda:${CUDA_VERSION}-cudnn8-runtime-ubuntu${UBUNTU_VERSION} AS base

# Avoid interactive prompts during package install


ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \


python3.11 python3.11-pip python3.11-dev \
libgomp1 curl tini git && \
update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1 &&
\
update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 && \
rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install PyTorch with CUDA support


COPY [Link] .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install torch==2.3.0 torchvision==0.18.0 --index-url
[Link] && \

Page 12 of 25
Docker Coding Reference — AI Engineers Edition

pip install -r [Link]

# Non-root user
RUN useradd --no-create-home --uid 1001 appuser && \
mkdir -p /app/models /app/outputs && \
chown -R appuser:appuser /app

COPY --chown=appuser:appuser ./src /app/src

ENV PYTHONUNBUFFERED=1 \
CUDA_VISIBLE_DEVICES=0 \ # Default to first GPU
PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512 # Reduce CUDA OOM

USER appuser
EXPOSE 8000
VOLUME /app/models

HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=3 \


CMD python -c "import torch; assert [Link].is_available()" || exit 1

ENTRYPOINT ["/usr/bin/tini", "--"]


CMD ["python", "-m", "[Link]", "--device", "cuda"]

Dockerfile C: Jupyter Notebook Server for ML Development


FROM pytorch/pytorch:2.3.0-cuda12.1-cudnn8-runtime

WORKDIR /workspace

RUN apt-get update && apt-get install -y --no-install-recommends \


git vim curl wget htop && \
rm -rf /var/lib/apt/lists/*

COPY [Link] .
RUN pip install --no-cache-dir \
jupyterlab==4.1.0 \
ipywidgets \
matplotlib seaborn plotly \
-r [Link]

ENV JUPYTER_ENABLE_LAB=yes \
JUPYTER_TOKEN=mysecrettoken \ # Change in production!
PYTHONPATH=/workspace/src

EXPOSE 8888
VOLUME /workspace

# Jupyter doesn't need root; run as user 1000 (common UID)


RUN useradd -m -u 1000 jupyter && chown -R jupyter /workspace
USER jupyter

CMD ["jupyter", "lab", "--ip=[Link]", "--port=8888", "--no-browser",


"--[Link]=${JUPYTER_TOKEN}"]

Page 13 of 25
Docker Coding Reference — AI Engineers Edition

# Run it: docker run --gpus all -p 8888:8888 -v $(pwd):/workspace mylab

Page 14 of 25
Docker Coding Reference — AI Engineers Edition

Section 3: Docker Compose — Complete Reference


3.1 Complete [Link] for AI Stack
# [Link] — Complete AI ML Stack
# Run: docker compose up -d
# Run specific profile: docker compose --profile monitoring up -d

name: ai-stack # Project name (default: directory name)

services:

# ── Model Inference API ───────────────────────────────────


model-api:
build:
context: . # Build context
dockerfile: [Link]
target: runtime # Stop at this multi-stage target
args:
PYTHON_VERSION: '3.11'
image: my-model-api:${APP_VERSION:-latest} # Built image name
container_name: model-api
restart: unless-stopped
ports:
- "[Link]:8000:8000" # Only on localhost (nginx in front)
environment:
- PYTHONUNBUFFERED=1
- MODEL_NAME=${MODEL_NAME:-llama-3-8b}
- LOG_LEVEL=INFO
- DB_HOST=postgres # Resolves via Docker DNS!
- REDIS_URL=redis://redis:6379
env_file:
- .[Link] # Secrets loaded from file at runtime
volumes:
- model-weights:/app/models # Named volume for model weights
- ./logs:/app/logs # Bind mount for logs
deploy:
resources:
limits:
memory: 16G # Hard RAM limit
cpus: '8'
reservations:
devices:
- driver: nvidia
count: 1 # Request 1 GPU
capabilities: [gpu] # Must specify for NVIDIA toolkit
healthcheck:
test: ["CMD", "curl", "-f", "[Link]
interval: 30s
timeout: 10s
start_period: 120s # Wait 2min before first check (model load)
retries: 3
depends_on:
postgres:
condition: service_healthy # Wait until postgres is ready

Page 15 of 25
Docker Coding Reference — AI Engineers Edition

redis:
condition: service_healthy
networks:
- backend # Internal network
- frontend # Network shared with nginx
logging:
driver: json-file
options:
max-size: '50m'
max-file: '5'

# ── PostgreSQL Database ────────────────────────────────────


postgres:
image: postgres:16-alpine
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_DB: mlops
POSTGRES_USER: mluser
POSTGRES_PASSWORD_FILE: /run/secrets/db_password # Secret file
secrets:
- db_password
volumes:
- postgres-data:/var/lib/postgresql/data # Persist DB data
- ./[Link]:/docker-entrypoint-initdb.d/[Link]:ro # Init script
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mluser -d mlops"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 5
networks:
- backend

# ── Redis Cache ─────────────────────────────────────────────


redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
command: redis-server --maxmemory 2gb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- backend

# ── Nginx Reverse Proxy ─────────────────────────────────────


nginx:
image: nginx:1.25-alpine
container_name: nginx
restart: unless-stopped
ports:

Page 16 of 25
Docker Coding Reference — AI Engineers Edition

- "80:80"
- "443:443"
volumes:
- ./nginx/[Link]:/etc/nginx/[Link]:ro
- ./nginx/certs:/etc/nginx/certs:ro
depends_on:
model-api:
condition: service_healthy
networks:
- frontend

# ── Grafana Monitoring ──────────────────── profile: monitoring ─


grafana:
image: grafana/grafana:10.3.0
profiles: [monitoring] # Only starts with --profile monitoring
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
networks:
- backend

# ── Model Downloader (one-off init container) ──────────────


model-init:
image: python:3.11-slim
profiles: [init] # Run manually: docker compose --profile init
run model-init
volumes:
- model-weights:/models
environment:
- HF_TOKEN=${HF_TOKEN}
command: ["python", "/[Link]", "--model", "meta-llama/Meta-Llama-3-8B"]

# ── Networks ──────────────────────────────────────────────────
networks:
backend:
driver: bridge
name: ai-backend # Explicit name (not prefixed by project)
frontend:
driver: bridge

# ── Volumes ───────────────────────────────────────────────────
volumes:
model-weights:
name: ai-model-weights # Explicit name
postgres-data:
redis-data:
grafana-data:

# ── Secrets ───────────────────────────────────────────────────
secrets:
db_password:
file: ./secrets/db_password.txt # Plain text file, not committed to git

3.2 Docker Compose Commands — Complete Reference

Page 17 of 25
Docker Coding Reference — AI Engineers Edition

# ── Starting & Stopping ─────────────────────────────────────


docker compose up # Start all services (foreground)
docker compose up -d # Detached (background)
docker compose up --build # Rebuild images before starting
docker compose up --no-deps model-api # Start only model-api (skip deps)
docker compose up --profile monitoring # Also start monitoring-profile services
docker compose up --scale model-api=3 # Run 3 replicas of model-api

docker compose down # Stop & remove containers + networks


docker compose down --volumes # Also remove volumes (DATA LOSS!)
docker compose down --rmi all # Also remove built images

docker compose stop # Stop without removing containers


docker compose start # Start stopped containers
docker compose restart model-api # Restart specific service
docker compose pause # Pause all services
docker compose unpause # Resume

# ── Status & Monitoring ─────────────────────────────────────


docker compose ps # List containers and status
docker compose ps --format json # JSON output for scripting
docker compose logs # All service logs
docker compose logs -f model-api # Follow logs for specific service
docker compose logs --tail=50 # Last 50 lines from each service
docker compose top # Processes in each container
docker compose stats # Live resource usage

# ── Exec & Run ──────────────────────────────────────────────


docker compose exec model-api bash # Shell in running container
docker compose exec postgres psql -U mluser # Run command in service
docker compose run --rm model-api python [Link] migrate # One-off command

# ── Build & Push ─────────────────────────────────────────────


docker compose build # Build all services with build config
docker compose build --no-cache # Force full rebuild
docker compose build model-api # Build specific service
docker compose push # Push built images to registry
docker compose pull # Pull latest images from registry

# ── Config & Validation ─────────────────────────────────────


docker compose config # Validate and view resolved compose config
docker compose config --services # List service names
docker compose config --volumes # List volume names

# ── Multiple compose files (overriding) ─────────────────────


docker compose -f [Link] -f [Link] up
# [Link] auto-merges with [Link] — use for dev overrides

Page 18 of 25
Docker Coding Reference — AI Engineers Edition

Section 4: Real AI/ML Code Patterns


4.1 FastAPI + Model Loading Pattern
# src/[Link] — Production FastAPI with proper Docker patterns
import os, signal, logging, asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch

[Link](level=[Link], format='%(asctime)s %(levelname)s


%(message)s')
log = [Link](__name__)

# Read config from environment (twelve-factor pattern):


MODEL_PATH = [Link]('MODEL_PATH', '/app/models/[Link]')
DEVICE = [Link]('DEVICE', 'cuda' if [Link].is_available() else 'cpu')
MAX_BATCH_SIZE = int([Link]('MAX_BATCH_SIZE', '8'))

model = None # Global model reference

# Lifespan handler: runs at startup and shutdown


@asynccontextmanager
async def lifespan(app: FastAPI):
global model
[Link](f'Loading model from {MODEL_PATH} on {DEVICE}')
model = [Link](MODEL_PATH, map_location=DEVICE)
[Link]()
[Link]('Model loaded. Ready to serve.')
yield # Container runs here
[Link]('Shutdown: releasing model')
del model
[Link].empty_cache()

app = FastAPI(lifespan=lifespan, title='Model API')

class InferenceRequest(BaseModel):
text: str
max_tokens: int = 512

@[Link]('/health') # Required for Docker HEALTHCHECK


async def health():
if model is None:
raise HTTPException(503, 'Model not loaded')
return {'status': 'healthy', 'device': DEVICE,
'cuda_available': [Link].is_available()}

@[Link]('/infer')
async def infer(req: InferenceRequest):
with torch.inference_mode():
# ... run model inference ...
result = model([Link])

Page 19 of 25
Docker Coding Reference — AI Engineers Edition

return {'output': result}

4.2 [Link] Best Practices for Docker


# [Link] — Pin ALL versions for reproducibility in Docker

# ── Core Framework ─────────────────────────────────────────


fastapi==0.111.0
uvicorn[standard]==0.29.0
pydantic==2.7.1

# ── ML Libraries ────────────────────────────────────────────
# Note: torch pinned via --index-url in Dockerfile (CUDA version specific)
torch==2.3.0
transformers==4.41.1
accelerate==0.30.1
sentencepiece==0.2.0

# ── Database ────────────────────────────────────────────────
sqlalchemy==2.0.30
asyncpg==0.29.0
alembic==1.13.1

# ── Caching ─────────────────────────────────────────────────
redis==5.0.4

# ── Monitoring ──────────────────────────────────────────────
prometheus-client==0.20.0
opentelemetry-sdk==1.24.0

# ── Separate files for different environments ───────────────


# [Link]: jupyter, pytest, black, mypy, etc.
# [Link]: pytest, pytest-asyncio, httpx (test client)
# [Link]: ONLY inference deps (smallest possible)

# Generate pinned requirements from loose requirements:


# pip-compile [Link] > [Link]
# (pip-compile from pip-tools package)

4.3 .env Files for Docker — Development vs Production


# .[Link] — committed to git (no real secrets)
APP_VERSION=dev
LOG_LEVEL=DEBUG
MODEL_NAME=tiny-test-model
DB_HOST=localhost
DB_PORT=5432
REDIS_URL=redis://localhost:6379

# .[Link] — NEVER commit to git, inject at deploy time


OPENAI_API_KEY=sk-... # Real secret

Page 20 of 25
Docker Coding Reference — AI Engineers Edition

HF_TOKEN=hf_... # Real secret


DB_PASSWORD=... # Real secret
SENTRY_DSN=[Link] # Real secret

# .gitignore — always exclude:


.[Link]
.[Link]
secrets/
*.env

# Use in Compose:
# env_file:
# - .[Link]
# - .[Link] ← overlays, production values win

# Or pass individually at runtime:


# docker run -e OPENAI_API_KEY=$OPENAI_API_KEY ...
# The $OPENAI_API_KEY comes from your shell, not from any file.

4.4 GPU Docker Compose for Multi-GPU Training


# [Link] — Multi-GPU training job
services:
trainer:
build:
context: .
dockerfile: [Link]
volumes:
- ./src:/app/src:ro # Code (read-only)
- /data/datasets:/data:ro # Dataset (read-only)
- ./checkpoints:/checkpoints # Save checkpoints to host
- ./logs/train:/app/logs
environment:
- MASTER_ADDR=localhost # For DDP (distributed training)
- MASTER_PORT=12355
- WORLD_SIZE=2 # Total GPUs across all nodes
- CUDA_VISIBLE_DEVICES=0,1 # Use GPUs 0 and 1
- HF_TOKEN=${HF_TOKEN} # From shell environment
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all # All GPUs
capabilities: [gpu]
limits:
memory: 128G
shm_size: '16gb' # Shared memory for PyTorch DataLoader
ulimits: # Increase for large training jobs
memlock:
soft: -1
hard: -1
ipc: host # Shared IPC for multi-GPU (alternative to
shm_size)

Page 21 of 25
Docker Coding Reference — AI Engineers Edition

command: ["torchrun", "--nproc_per_node=2", "[Link]",


"--epochs", "100", "--batch-size", "32"]

# Run it:
# docker compose -f [Link] up
# Check GPU usage: docker exec trainer nvidia-smi
# Follow logs: docker compose -f [Link] logs -f

4.5 Makefile for Docker Workflows


# Makefile — Standard Docker workflow shortcuts

.PHONY: build push run dev test clean logs shell

# Variables
IMAGE_NAME := my-model-api
REGISTRY := [Link]/myorg
GIT_SHA := $(shell git rev-parse --short HEAD)
VERSION := $(shell cat VERSION 2>/dev/null || echo 'dev')

# Build the production image


build:
docker build \
-t $(IMAGE_NAME):$(GIT_SHA) \
-t $(IMAGE_NAME):latest \
--build-arg APP_VERSION=$(VERSION) \
--cache-from $(REGISTRY)/$(IMAGE_NAME):latest \
.

# Push to registry
push: build
docker tag $(IMAGE_NAME):$(GIT_SHA) $(REGISTRY)/$(IMAGE_NAME):$(GIT_SHA)
docker tag $(IMAGE_NAME):$(GIT_SHA) $(REGISTRY)/$(IMAGE_NAME):latest
docker push $(REGISTRY)/$(IMAGE_NAME):$(GIT_SHA)
docker push $(REGISTRY)/$(IMAGE_NAME):latest

# Start full stack in background


run:
docker compose up -d

# Development with live code reload


dev:
docker compose -f [Link] -f [Link] up

# Run tests in container


test:
docker compose run --rm model-api pytest tests/ -v --tb=short

# Open shell in running container


shell:
docker compose exec model-api bash

# Follow logs

Page 22 of 25
Docker Coding Reference — AI Engineers Edition

logs:
docker compose logs -f model-api

# Clean everything
clean:
docker compose down --volumes --rmi local
docker system prune -f

# Download model weights to volume


init-model:
docker compose --profile init run --rm model-init

Page 23 of 25
Docker Coding Reference — AI Engineers Edition

Section 5: Debugging and Troubleshooting


5.1 Container Won't Start — Diagnosis
# Step 1: See why it exited
docker ps -a # Find the container, check STATUS and EXIT CODE
docker logs mycontainer # Read error output
docker inspect mycontainer | python -m [Link] # Full metadata

# Step 2: Override CMD to get a shell (bypass your broken entrypoint):


docker run -it --entrypoint bash myimage:v1
# Now you're inside — test your app manually:
python [Link] # Run directly and see the actual error
python -c 'import mymodule' # Test specific imports
env # Check environment variables
ls -la /app # Check file permissions
cat /app/[Link] # Check config file contents

# Step 3: Common exit codes:


# Exit 0 = process exited normally (restart policy 'on-failure' won't restart)
# Exit 1 = application error (check logs)
# Exit 137 = killed by OOM killer (out of memory, increase --memory)
# Exit 139 = segfault (bad native lib version)
# Exit 143 = killed by SIGTERM (graceful shutdown — normal)

5.2 Networking Issues


# Can't connect container-to-container:
docker network inspect mynet # Check which containers are on the network
docker exec api ping postgres # Test DNS resolution and connectivity
docker exec api curl [Link] # Test HTTP
docker exec api nslookup postgres # DNS lookup

# Check port mappings:


docker port mycontainer # What ports are published
netstat -tlnp | grep 8080 # Is port 8080 listening on host?
curl localhost:8080/health # Test from host

# Container can't reach internet:


docker exec mycontainer curl [Link] # Test outbound
docker exec mycontainer cat /etc/[Link] # Check DNS config
docker exec mycontainer route -n # Check routing table

5.3 Performance Issues


# Live resource monitoring:
docker stats # CPU/RAM/NET/IO for all containers
docker stats mycontainer # Specific container
docker exec mycontainer top # Process list inside container

Page 24 of 25
Docker Coding Reference — AI Engineers Edition

# GPU monitoring in container:


docker exec mycontainer nvidia-smi # GPU usage
docker exec mycontainer nvidia-smi dmon # Continuous GPU monitoring
docker run --gpus all nvidia/cuda:12.1.0-base nvidia-smi # Quick GPU test

# Memory issues — container OOMed:


docker inspect mycontainer | grep -i oom # Was OOM killer triggered?
dmesg | grep -i 'out of memory' # Host kernel OOM messages

# Image too large — analyze layers:


docker history myimage:v1 --human --format 'table {{.Size}} {{.CreatedBy}}'
# Install dive for deep layer analysis:
docker run --rm -it -v /var/run/[Link]:/var/run/[Link] \
wagoodman/dive myimage:v1

5.4 Build Issues


# See exactly what's happening in build:
docker build --progress=plain . # Show all RUN output (no condensing)
docker build --no-cache . # Force rebuild all layers

# Build context too large (slow uploads):


docker build . 2>&1 | head -5 # First line shows build context size
# If 'Sending build context to Docker daemon 2.5GB' — fix your .dockerignore

# Find what's in build context:


find . -not -path './.git/*' | sort # List all files that could be in context

# Test .dockerignore:
docker build --file /dev/null --tag test-context . # Builds with empty Dockerfile
# First line shows context size — should be small

# BuildKit debugging:
DOCKER_BUILDKIT=1 docker build --progress=plain . 2>&1 | tee [Link]

END OF DOCUMENT 2 — CODING REFERENCE


Refer to Document 1 (Concepts) for deep explanations of every topic covered in this coding guide.

Page 25 of 25

You might also like