Think of Docker like a vending machine for software. You press a button (run a command) and out pops exactly what you need — a perfectly packaged, ready-to-run application.
But just like a vending machine has buttons for different items, Docker has commands for different jobs — building, running, stopping, inspecting, cleaning, and shipping containers.
Every ML model deployment involves Docker commands. When you train a model, package it, push it to Oracle Container Registry (OCIR), or deploy it to OCI Container Instances — you're typing Docker commands.
📚 Commands We'll Cover
- 🔹 Group 1: Image Commands —
build,images,pull,push,tag,rmi,history,inspect - 🔹 Group 2: Container Commands —
run,ps,start,stop,rm,exec,logs,stats - 🔹 Group 3: Registry Commands —
login,logout,search - 🔹 Group 4: System Commands —
info,version,system prune,network,volume - 🔹 Group 5: Compose Commands —
up,down,scale,logs - 🔹 Real MLOps Workflows — chained command sequences for production
🗺️ The Docker Command Universe — One Diagram to Rule Them All
Dockerfile
↓ docker build
Local Image ──── docker push ────▶ OCIR Image ──── docker pull ────▶ OCI Instance
↓ docker run ↓ docker run
Container Container
↓ docker logs / exec / stats
Monitor & Debug
docker stop → docker rm → docker rmi → docker system prune
🖼️ Group 1: Image Commands
Images are the blueprints for your containers. These commands let you create, list, tag, push, pull, and delete them. Think of images as the recipe — containers are the meal you cook from it.
1. docker build — Create an Image from a Dockerfile
What it does:
Reads your Dockerfile line by line and builds a Docker image.
Like following a recipe step by step until the dish is ready.
# Most common — build from current directory, give it a name and version tag
docker build -t fraud-model:1.0 .
# Build with a build argument (e.g. specify environment)
docker build -t fraud-model:1.0 --build-arg environment=production .
# Build from a specific Dockerfile (not the default)
docker build -t fraud-model:1.0 -f docker/Dockerfile.prod .
# Build without using any cached layers (fresh build from scratch)
docker build -t fraud-model:1.0 --no-cache .
# Build and see detailed output for each layer
docker build -t fraud-model:1.0 --progress=plain .
. at the end means:
"Use the current folder as the build context."
Docker sends all files in this folder to the Docker engine.
That's why .dockerignore matters — to exclude large unnecessary files!
2. docker images — List All Local Images
What it does: Shows every Docker image stored on your machine — like opening your fridge and seeing all the meal-prep containers.
# List all images
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# fraud-model 1.0 a9f3b2c1d8e4 2 hours ago 612MB
# fraud-model 2.0 b8d4e7f2c3a1 5 days ago 598MB
# python 3.10-slim-buster c2e8f1b4... 2 weeks ago 125MB
# List images for a specific repository only
docker images fraud-model
# Show only image IDs (useful for scripting)
docker images -q
# Show all images including intermediate layers
docker images -a
# Filter images by label
docker images --filter "label=team=ml-engineering"
# Show images with custom format
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
docker images regularly
to track how many images are accumulating on your machine.
ML images are large (500 MB – 5 GB each).
Old unused ones quietly eat up your disk.
3. docker pull — Download an Image from a Registry
What it does: Downloads a Docker image from a registry to your local machine. Like downloading an app from an app store — but for containers.
# Pull a specific Python base image
docker pull python:3.10-slim-buster
# Pull from Oracle Container Registry (OCIR)
docker pull ap-mumbai-1.ocir.io/mytenancy/fraud-model:2.0
# Pull the latest tag (NOT recommended for production — always pin versions!)
docker pull python:latest
# Pull a specific digest (most precise — guaranteed exact image)
docker pull python@sha256:a3f7b2c19d4e8f6a1b2c3d4e5f6789ab...
# Pull all tags of a repository
docker pull --all-tags python
:latest in production!
docker pull python:latest gives you whatever is "latest" today —
which changes without warning and will break your ML model.
Always pin exact versions: python:3.10.12-slim-buster
4. docker push — Upload an Image to a Registry
What it does: Uploads your locally-built image to a registry (like OCIR) so it can be pulled and run on OCI servers. Like uploading a file to the cloud so others can download it.
# Push to Oracle Container Registry (OCIR)
docker push ap-mumbai-1.ocir.io/mytenancy/fraud-model:2.0
# Push all tags of an image
docker push --all-tags ap-mumbai-1.ocir.io/mytenancy/fraud-model
# Practical full push sequence:
# Step 1 — Build
docker build -t fraud-model:2.0 .
# Step 2 — Tag with full OCIR path
docker tag fraud-model:2.0 ap-mumbai-1.ocir.io/mytenancy/fraud-model:2.0
# Step 3 — Push
docker push ap-mumbai-1.ocir.io/mytenancy/fraud-model:2.0
5. docker tag — Give an Image a New Name/Label
What it does: Creates a new alias (tag) for an existing image. Like putting a different label on the same jar of jam — the contents are identical, only the label changes. No data is duplicated. Just a new pointer.
# Tag local image with full OCIR registry path (required before push!)
docker tag fraud-model:2.0 \
ap-mumbai-1.ocir.io/mytenancy/fraud-model:2.0
# Add a 'latest' alias alongside the versioned tag
docker tag fraud-model:2.0 fraud-model:latest
# Tag with git commit hash (great for traceability in CI/CD)
docker tag fraud-model:2.0 fraud-model:$(git rev-parse --short HEAD)
# Tag for promotion: dev → staging → production
docker tag fraud-model:2.0-dev fraud-model:2.0-staging
docker tag fraud-model:2.0-staging fraud-model:2.0-prod
Use version + commit hash for full traceability. Example:
fraud-model:2.0-a9f3b2cThis tells you the model version AND exactly which code commit produced it. In 6 months you can reproduce the exact image.
6. docker rmi — Delete a Local Image
What it does: Removes one or more images from your local machine. Like deleting a recipe book you no longer need — frees up disk space immediately.
# Remove a specific image by name and tag
docker rmi fraud-model:1.0
# Remove by image ID
docker rmi a9f3b2c1d8e4
# Force remove (even if a stopped container still references it)
docker rmi -f fraud-model:1.0
# Remove multiple images at once
docker rmi fraud-model:1.0 fraud-model:1.1 python:3.9-slim
# Remove ALL dangling images (untagged intermediate layers — safe to delete)
docker rmi $(docker images -f "dangling=true" -q)
# Remove ALL local images (nuclear option — use with caution!)
docker rmi $(docker images -q)
7. docker history — See Every Layer in an Image
What it does: Shows every layer that makes up a Docker image — what command created it, when, and how big it is. Like an X-ray that shows all the internal layers of your image.
# Show full image history
docker history fraud-model:2.0
# IMAGE CREATED CREATED BY SIZE
# a9f3b2c1d8e4 2 hours ago ENTRYPOINT ["/app/entrypoint.sh"] 0B
# b8d4e7f2c3a1 2 hours ago RUN chmod +x /app/entrypoint.sh 0B
# c9e5f8a3b2d1 2 hours ago COPY . /app 18.4MB
# d7f1e4b9c3a2 3 hours ago RUN pip3 install -r requirements.txt 412MB ← biggest!
# e6c2f7a8b4d3 3 hours ago COPY requirements.txt /app/ 1.2kB
# f5b8e3c9d1a4 3 hours ago RUN apt-get install build-essential 52MB
# a4c7f2b6e8d5 3 hours ago WORKDIR /app 0B
# python:3.10 2 weeks ago ... 125MB
# Show full command (don't truncate long commands)
docker history --no-trunc fraud-model:2.0
# Show only sizes — great for optimizing your image
docker history --format "{{.Size}}\t{{.CreatedBy}}" fraud-model:2.0
docker history to find which layer is bloating your image.
The pip install layer is almost always the largest.
If it's over 1 GB, consider multi-stage builds or a slimmer base image.
8. docker inspect — Get Full Metadata of an Image or Container
What it does: Returns full JSON metadata about an image or container — every environment variable, port, volume mount, layer digest, and configuration setting. The most detailed view Docker offers.
# Inspect an image
docker inspect fraud-model:2.0
# Inspect a running container
docker inspect fraud-api-prod
# Extract just one field using --format (saves hunting through JSON)
# Get the exposed port
docker inspect --format='{{.Config.ExposedPorts}}' fraud-model:2.0
# Get the ENTRYPOINT command
docker inspect --format='{{.Config.Entrypoint}}' fraud-model:2.0
# Get ALL environment variables
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' fraud-api-prod
# Get container IP address (useful for debugging networking)
docker inspect --format='{{.NetworkSettings.IPAddress}}' fraud-api-prod
# Get when the container was started
docker inspect --format='{{.State.StartedAt}}' fraud-api-prod
📦 Group 2: Container Commands
Containers are the running instances of images. These commands control the lifecycle of containers — from start to stop, from monitoring to debugging.
9. docker run — Create and Start a Container
What it does: This is the most important Docker command. It creates a brand new container from an image AND starts it immediately. Like pressing "Start" on a video game — the image is the game disc, the container is the game session that begins. 🎮
# ── BASIC ─────────────────────────────────────────────────────────────
# Run and see output in terminal (foreground — Ctrl+C to stop)
docker run fraud-model:2.0
# Run in the background (detached mode — returns container ID)
docker run -d fraud-model:2.0
# Run with a friendly name (easier than using container IDs)
docker run -d --name fraud-api fraud-model:2.0
# ── PORT MAPPING ───────────────────────────────────────────────────────
# Format: -p HOST_PORT:CONTAINER_PORT
# Map container port 8083 to your laptop's port 8083
docker run -d -p 8083:8083 --name fraud-api fraud-model:2.0
# Map to a different host port (useful when 8083 is already in use)
docker run -d -p 9090:8083 --name fraud-api-v2 fraud-model:2.0
# Map multiple ports
docker run -d -p 8083:8083 -p 9229:9229 fraud-model:2.0
# ── ENVIRONMENT VARIABLES ──────────────────────────────────────────────
# Pass a single environment variable
docker run -d -p 8083:8083 \
-e ENVIRONMENT=production \
fraud-model:2.0
# Pass multiple environment variables
docker run -d -p 8083:8083 \
-e ENVIRONMENT=production \
-e LOG_LEVEL=INFO \
-e OCI_REGION=ap-mumbai-1 \
-e MODEL_PATH=/app/models/fraud_model.pkl \
--name fraud-api \
fraud-model:2.0
# Load env vars from a file (BEST PRACTICE — keeps secrets out of CLI history)
docker run -d -p 8083:8083 \
--env-file .env.production \
--name fraud-api \
fraud-model:2.0
# ── VOLUME MOUNTS ──────────────────────────────────────────────────────
# Format: -v HOST_PATH:CONTAINER_PATH[:ro]
# Mount a local folder into the container (for loading models without rebuilding)
docker run -d -p 8083:8083 \
-v $(pwd)/models:/app/models \
--name fraud-api \
fraud-model:2.0
# Mount as READ-ONLY (prevents container from modifying your local files)
docker run -d -p 8083:8083 \
-v $(pwd)/models:/app/models:ro \
--name fraud-api \
fraud-model:2.0
# ── RESOURCE LIMITS ────────────────────────────────────────────────────
# Prevent one container from starving other processes on the machine
docker run -d -p 8083:8083 \
--memory="2g" \ # max 2 GB RAM
--cpus="1.5" \ # max 1.5 CPU cores
--name fraud-api \
fraud-model:2.0
# ── AUTO-RESTART ───────────────────────────────────────────────────────
# Restart policy for production deployments
docker run -d -p 8083:8083 \
--restart unless-stopped \ # restart on crash, but not if manually stopped
--name fraud-api \
fraud-model:2.0
# Other restart options:
# --restart no → never restart (default)
# --restart always → always restart (even after docker daemon restart)
# --restart on-failure:3 → restart up to 3 times on non-zero exit
# ── INTERACTIVE SHELL ──────────────────────────────────────────────────
# Open a shell INSIDE the container (great for debugging!)
docker run -it fraud-model:2.0 /bin/bash
# Now you're inside! Explore files, test Python imports, debug issues.
# Type 'exit' to leave.
# Run a quick one-off command and exit
docker run --rm fraud-model:2.0 python -c "import torch; print(torch.__version__)"
# --rm = automatically remove the container when it exits (keeps things tidy)
docker run flags to memorize:-d = run in background (detached)-p = map ports (host:container)-e = set environment variable--name = give it a friendly name-v = mount a folder--rm = auto-delete when done-it = interactive terminal (for debugging)
10. docker ps — List Running Containers
What it does: Shows all currently running containers. Like the Activity Monitor on your laptop — it shows you what's alive and consuming resources right now.
# List only RUNNING containers
docker ps
# CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
# c4f8a2b3d9e1 fraud-model:2.0 "/app/entrypoint.sh" Up 3 hours 0.0.0.0:8083->8083/tcp fraud-api
# d5e7b3c1f8a2 redis:7.2-alpine "docker-entrypoint…" Up 3 hours 6379/tcp redis-cache
# List ALL containers (including stopped ones)
docker ps -a
# Show only container IDs (for scripting)
docker ps -q
# Show only IDs of ALL containers (including stopped)
docker ps -aq
# Filter by name
docker ps --filter "name=fraud-api"
# Filter by status
docker ps --filter "status=exited" # show only stopped containers
docker ps --filter "status=running" # show only running
# Custom format (cleaner output)
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Names Status Ports
# fraud-api Up 3 hours 0.0.0.0:8083->8083/tcp
# redis-cache Up 3 hours 6379/tcp
11. docker start & docker stop — Resume or Pause a Container
What they do:
stop gracefully shuts down a running container
(sends SIGTERM signal, waits 10 seconds, then forces kill).
start restarts a stopped container —
like pressing pause and play on a video. The container state is preserved.
# Stop a container gracefully (waits up to 10 seconds for clean shutdown)
docker stop fraud-api
# Stop with custom wait timeout (useful for models that take time to shut down)
docker stop --time 30 fraud-api # wait up to 30 seconds
# Force-kill immediately (no graceful shutdown — use only when stop hangs!)
docker kill fraud-api
# Restart a stopped container (keeps same config — ports, env vars, volumes)
docker start fraud-api
# Restart a RUNNING container (stop + start in one command)
docker restart fraud-api
# Stop multiple containers at once
docker stop fraud-api redis-cache postgres-db
# Stop ALL running containers
docker stop $(docker ps -q)
docker stop over docker kill.
stop gives your ML API time to finish processing in-flight requests
before shutting down. kill cuts the power immediately —
requests get dropped and data can corrupt.
12. docker rm — Delete a Stopped Container
What it does: Permanently removes a stopped container. Note: this does NOT delete the image. Like throwing away a used meal container — the recipe is still in your cookbook.
# Remove a stopped container
docker rm fraud-api
# Force-remove a RUNNING container (stop + remove in one command)
docker rm -f fraud-api
# Remove multiple containers
docker rm fraud-api redis-cache
# Remove ALL stopped containers (safe cleanup)
docker rm $(docker ps -aq -f status=exited)
# One-liner: stop and remove a running container
docker stop fraud-api && docker rm fraud-api
# Better: use --rm in docker run to auto-delete when it stops
docker run --rm fraud-model:2.0
13. docker exec — Run a Command Inside a Running Container
What it does: Executes a command inside a container that is already running. Like teleporting into a car that's already driving — you can interact with everything inside without stopping or restarting it. This is the #1 debugging tool for ML container problems. 🔧
# Open an interactive bash shell INSIDE a running container
docker exec -it fraud-api bash
# You are now INSIDE the container!
# → ls /app (see your files)
# → python (test Python)
# → env | grep MODEL (check env variables)
# → exit (leave the container)
# Run a single command and exit (non-interactive)
docker exec fraud-api ls /app/models
# Check Python version inside the container
docker exec fraud-api python --version
# Test if your model loads correctly
docker exec fraud-api python -c "
import joblib
model = joblib.load('/app/models/fraud_model.pkl')
print('Model type:', type(model))
print('Model loaded successfully ✅')
"
# Check environment variables inside the container
docker exec fraud-api env | grep -E "MODEL|ENVIRONMENT|OCI"
# Check disk usage inside the container
docker exec fraud-api df -h
# Run as a specific user (for permission debugging)
docker exec -u root -it fraud-api bash
docker exec -it CONTAINER bash is your most powerful debugging command.
When your ML model isn't behaving in production,
SSH into the container and investigate directly.
Check files, test imports, print environment variables —
all without stopping the live service.
14. docker logs — View Container Output
What it does: Shows everything the container has printed to the terminal (stdout + stderr) since it started. Like reading the diary of your container — every print statement, every error, every API request logged. 📖
# Show ALL logs since container started
docker logs fraud-api
# Follow logs in real-time (like tail -f — most useful!)
docker logs -f fraud-api
# Show only the last 50 lines
docker logs --tail 50 fraud-api
# Follow AND show only last 50 lines (most common combo)
docker logs -f --tail 50 fraud-api
# Show logs with timestamps
docker logs --timestamps fraud-api
# Show logs since a specific time
docker logs --since "2025-03-10T10:00:00" fraud-api
# Show logs between two times
docker logs --since "1h" --until "30m" fraud-api # between 1h and 30min ago
# Example output you'd see:
# 2025-03-10T10:23:01.123Z INFO: Loading model from /app/models/fraud_model.pkl
# 2025-03-10T10:23:04.456Z INFO: ✅ Model loaded in 3.3 seconds
# 2025-03-10T10:23:04.789Z INFO: Application startup complete
# 2025-03-10T10:23:05.012Z INFO: Uvicorn running on http://0.0.0.0:8083
# 2025-03-10T10:25:12.345Z INFO: POST /predict - user=12345 score=0.92 BLOCK 1.8ms
15. docker stats — Real-Time Resource Usage
What it does: Shows a live dashboard of CPU, RAM, network, and disk usage for your running containers. Like the Activity Monitor — but for containers specifically.
# Live dashboard for ALL running containers (refreshes every second)
docker stats
# CONTAINER ID NAME CPU % MEM USAGE / LIMIT NET I/O BLOCK I/O
# c4f8a2b3d9e1 fraud-api 12.3% 1.2GB / 4GB 45.2MB / 8.1MB 0B / 0B
# d5e7b3c1f8a2 redis-cache 0.1% 12.4MB / 512MB 1.2MB / 800kB 0B / 0B
# Monitor only specific containers
docker stats fraud-api redis-cache
# Single snapshot (no live update — useful for scripts)
docker stats --no-stream
# Custom format showing only what matters
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
MEM USAGE closely for ML models!
If RAM usage keeps climbing and never drops,
your model has a memory leak —
likely loading the model inside the endpoint function
instead of once at startup.
Memory should stay constant once the model is loaded.
🔐 Group 3: Registry Commands
Registry commands control your connection to container registries like Oracle Container Registry (OCIR) — where your ML images live in the cloud.
16. docker login — Authenticate with a Registry
What it does: Logs in to a container registry so you can push and pull images. Like logging into an app before you can download anything.
# Login to Oracle Container Registry (OCIR)
# Username format: tenancy-namespace/oci-username (or federated user email)
docker login ap-mumbai-1.ocir.io \
--username "mytenancy/alice@company.com" \
--password "OCI-Auth-Token-here"
# Login Succeeded ✅
# SECURE: Pass password via stdin (avoids it appearing in shell history!)
echo "$OCI_AUTH_TOKEN" | docker login ap-mumbai-1.ocir.io \
--username "mytenancy/alice@company.com" \
--password-stdin
# Login to Docker Hub (for pulling public base images)
docker login
# Login to a different OCI region registry
docker login eu-frankfurt-1.ocir.io \
--username "mytenancy/alice@company.com" \
--password-stdin
~/.bash_history) in plain text.
Always use --password-stdin or environment variables:
echo "$OCI_AUTH_TOKEN" | docker login ... --password-stdin
17. docker logout — Sign Out from a Registry
# Logout from OCIR (removes stored credentials from ~/.docker/config.json)
docker logout ap-mumbai-1.ocir.io
# Logout from Docker Hub
docker logout
18. docker search — Find Public Images
# Search Docker Hub for official Python images
docker search python
# Search for PyTorch images
docker search pytorch
# Filter to only official images
docker search --filter "is-official=true" python
# Show at most 5 results
docker search --limit 5 pytorch
🔧 Group 4: System Commands
System commands give you information about Docker itself and help you keep your machine clean and healthy.
19. docker version & docker info — System Information
# Show Docker version (Client + Server)
docker version
# Client: Docker Engine - Community
# Version: 26.0.0
# API version: 1.45
# Server: Docker Engine - Community
# Version: 26.0.0
# Show detailed system info (storage, number of containers/images, etc.)
docker info
# Useful fields in docker info:
# Containers: 3 (Running: 2, Stopped: 1)
# Images: 8
# Docker Root Dir: /var/lib/docker
# Total Memory: 15.54 GiB
# CPUs: 8
20. docker system prune — The Master Cleanup Command
What it does: Removes all stopped containers, unused networks, dangling images, and optionally unused volumes — in one sweep. Like running a full disk cleanup on your machine. 🧹
# Remove all stopped containers + dangling images + unused networks
# (asks for confirmation first)
docker system prune
# WARNING! This will remove:
# 3 stopped containers
# 2 networks not used by at least one container
# 1 dangling image
# Total reclaimed space: 1.42 GB
# Are you sure you want to continue? [y/N] y
# Skip confirmation prompt (for CI/CD pipelines)
docker system prune -f
# NUCLEAR: Also remove ALL unused images (not just dangling ones)
# This frees MUCH more space but means re-downloading base images
docker system prune -a
# MOST NUCLEAR: Remove everything including volumes (CAREFUL — deletes data!)
docker system prune -a --volumes
# See what's taking up space before pruning
docker system df
# TYPE TOTAL ACTIVE SIZE RECLAIMABLE
# Images 8 2 4.521GB 3.108GB (68%)
# Containers 3 2 18.4MB 12.2MB (66%)
# Local Volumes 2 1 890.2MB 445.1MB (50%)
# Build Cache 15 0 2.1GB 2.1GB
docker system df first to see exactly how much space
you'll reclaim before committing to prune.
Run docker system prune -a monthly on your dev machine
to prevent Docker from eating your entire hard drive.
21. docker network — Manage Container Networking
# List all Docker networks
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# a1b2c3d4e5f6 bridge bridge local ← default
# b2c3d4e5f6a7 host host local
# c3d4e5f6a7b8 ml-network bridge local ← custom (from compose)
# Create a custom network (containers on same network can talk by name)
docker network create ml-network
# Inspect a network (see which containers are connected)
docker network inspect ml-network
# Connect a running container to a network
docker network connect ml-network fraud-api
# Disconnect from a network
docker network disconnect ml-network fraud-api
# Remove unused networks
docker network prune
22. docker volume — Manage Persistent Storage
# List all volumes
docker volume ls
# DRIVER VOLUME NAME
# local fraud_postgres-data
# local fraud_redis-data
# Create a named volume
docker volume create ml-model-storage
# Inspect a volume (see where data is stored on disk)
docker volume inspect ml-model-storage
# Use a named volume in docker run
docker run -d -p 8083:8083 \
-v ml-model-storage:/app/models \
fraud-model:2.0
# Remove a specific volume (WARNING: permanent data loss!)
docker volume rm ml-model-storage
# Remove all unused volumes
docker volume prune
🐙 Group 5: Docker Compose Commands
Docker Compose manages multi-container applications
defined in a docker-compose.yaml file.
Instead of running 4 separate docker run commands,
you use one Compose command to orchestrate everything.
23. Core Compose Commands
# ── START ──────────────────────────────────────────────────────────────
# Start all services in background (builds images if they don't exist)
docker compose up -d
# Start and force rebuild ALL images (even if they haven't changed)
docker compose up -d --build
# Start only specific services
docker compose up -d fraud-api redis-cache
# ── STOP ───────────────────────────────────────────────────────────────
# Stop all services (keeps containers and volumes — fast restart)
docker compose stop
# Stop AND remove containers + networks (clean slate — volumes preserved)
docker compose down
# Stop AND remove containers + networks + volumes (CAREFUL: deletes data!)
docker compose down -v
# ── MONITORING ─────────────────────────────────────────────────────────
# Check status of all services
docker compose ps
# NAME SERVICE STATUS PORTS
# fraud-api fraud-api running 0.0.0.0:8083->8083/tcp
# redis-cache redis-cache running 6379/tcp
# postgres-db postgres-db running 5432/tcp
# Follow logs from ALL services
docker compose logs -f
# Follow logs from one service only
docker compose logs -f fraud-api
# Show last 100 lines from all services
docker compose logs --tail 100
# ── SCALING ────────────────────────────────────────────────────────────
# Scale the API to 3 instances (load testing!)
docker compose up -d --scale fraud-api=3
# ── MAINTENANCE ────────────────────────────────────────────────────────
# Execute a command inside a Compose service container
docker compose exec fraud-api bash
docker compose exec fraud-api python -c "import sklearn; print(sklearn.__version__)"
# Restart one service without affecting others
docker compose restart fraud-api
# Pull latest images for all services (for updates)
docker compose pull
# See resource usage for all compose services
docker compose top
🔄 Real MLOps Workflows — Chained Command Sequences
In production, Docker commands are always chained together. Here are the exact sequences you'll use every day as an MLOps engineer.
Workflow 1: Build & Deploy a New Model Version to OCI
#!/bin/bash
# deploy_to_oci.sh — Full build → push → deploy sequence
set -e # Exit on any error
MODEL_VERSION="2.1.0"
OCI_REGION="ap-mumbai-1"
TENANCY="mytenancy"
OCIR_IMAGE="${OCI_REGION}.ocir.io/${TENANCY}/fraud-model:${MODEL_VERSION}"
echo "🏗️ Step 1: Build Docker image..."
docker build \
-t fraud-model:${MODEL_VERSION} \
--build-arg environment=production \
.
echo "📊 Step 2: Check image size..."
docker images fraud-model:${MODEL_VERSION}
echo "🔐 Step 3: Login to OCIR..."
echo "$OCI_AUTH_TOKEN" | docker login ${OCI_REGION}.ocir.io \
--username "${TENANCY}/${OCI_USERNAME}" \
--password-stdin
echo "🏷️ Step 4: Tag with OCIR path..."
docker tag fraud-model:${MODEL_VERSION} ${OCIR_IMAGE}
echo "📤 Step 5: Push to OCIR..."
docker push ${OCIR_IMAGE}
echo "🔄 Step 6: Pull and restart on OCI Compute..."
ssh opc@${OCI_INSTANCE_IP} "
docker pull ${OCIR_IMAGE} &&
docker stop fraud-api || true &&
docker rm fraud-api || true &&
docker run -d \
--name fraud-api \
--restart unless-stopped \
-p 8083:8083 \
--env-file /home/opc/.env.production \
${OCIR_IMAGE}
"
echo "✅ Deployment complete! Testing health endpoint..."
sleep 5
curl -f http://${OCI_INSTANCE_IP}:8083/health
echo "🎉 Fraud model v${MODEL_VERSION} deployed successfully!"
Workflow 2: Debug a Broken Container
# Container is crashing — investigate!
# Step 1: Check if it's running (or if it crashed)
docker ps -a | grep fraud-api
# Step 2: Read the logs to find the error
docker logs --tail 100 fraud-api
# Step 3: Check resource usage (is it out of memory?)
docker stats --no-stream fraud-api
# Step 4: Try to run it interactively to reproduce the issue
docker run -it \
-e ENVIRONMENT=production \
--env-file .env.production \
fraud-model:2.0 bash
# Inside container: try to manually start the app
# → python src/api/main.py
# → check error messages directly
# Step 5: Inspect the container's environment variables
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' fraud-api
# Step 6: Check if model file exists inside the container
docker exec fraud-api ls -lh /app/models/
# Step 7: Test model loading directly
docker exec fraud-api python -c "
import joblib
try:
m = joblib.load('/app/models/fraud_model.pkl')
print('✅ Model loaded OK:', type(m))
except Exception as e:
print('❌ Model load failed:', e)
"
Workflow 3: Monthly Cleanup Routine
# Run this monthly to keep your machine healthy
echo "📊 Current Docker disk usage:"
docker system df
echo ""
echo "🔍 Stopped containers to remove:"
docker ps -a --filter status=exited --format "table {{.Names}}\t{{.Status}}"
echo ""
echo "🗑️ Removing stopped containers..."
docker container prune -f
echo ""
echo "🖼️ Removing dangling images (untagged)..."
docker image prune -f
echo ""
echo "🌐 Removing unused networks..."
docker network prune -f
echo ""
echo "📊 Docker disk usage AFTER cleanup:"
docker system df
echo ""
echo "✅ Cleanup complete!"
📌 The Ultimate Docker Commands Quick Reference Card
| Command | What It Does | Most Used Flag |
|---|---|---|
docker build -t name:tag . |
Build image from Dockerfile | --no-cache |
docker images |
List all local images | -a |
docker pull image:tag |
Download image from registry | — |
docker push image:tag |
Upload image to registry | — |
docker tag src dst |
Alias/rename an image | — |
docker rmi image:tag |
Delete a local image | -f |
docker history image |
Show image layers + sizes | --no-trunc |
docker inspect name |
Full JSON metadata | --format |
docker run -d -p 8083:8083 |
Create & start container | --name --env-file |
docker ps |
List running containers | -a |
docker stop name |
Graceful shutdown | --time 30 |
docker start name |
Resume stopped container | — |
docker restart name |
Stop + start | — |
docker rm name |
Delete stopped container | -f |
docker exec -it name bash |
Shell inside container | -it |
docker logs -f name |
Stream live logs | --tail 50 |
docker stats name |
Live CPU/RAM usage | --no-stream |
docker login registry |
Authenticate with registry | --password-stdin |
docker system df |
Show disk usage | — |
docker system prune -a |
Clean up everything unused | -f |
docker compose up -d |
Start all Compose services | --build |
docker compose down |
Stop & remove Compose services | -v |
✅ Best Practices & Common Mistakes
- ✅ Always use
--nameindocker run— IDs are hard to remember - ✅ Use
--env-fileinstead of multiple-eflags for cleaner commands - ✅ Use
--password-stdinfordocker login— keeps credentials out of shell history - ✅ Use
--restart unless-stoppedfor production ML APIs - ✅ Run
docker system dfmonthly anddocker system prune -ato reclaim space - ✅ Always tag images with a version AND a git hash for full traceability
- ✅ Use
docker exec -it container bashas your first debugging step - ✅ Use
docker logs -f --tail 50to follow live logs during deployment
- ❌ Never use
:latesttags in production — always pin exact versions - ❌ Never type credentials directly in
docker login— use stdin or env vars - ❌ Never use
docker killon production — usedocker stopfor graceful shutdown - ❌ Don't forget to
docker rmafterdocker stop— stopped containers still consume disk - ❌ Don't run
docker system prune -a --volumeson a production server — it deletes database data! - ❌ Don't use
--no-cachein every build — it defeats the entire point of layer caching
🏆 High Level Summary
- 🔹 Build:
docker build -t name:tag .— create image from Dockerfile - 🔹 List:
docker images— see what's on your machine - 🔹 Ship:
docker tag+docker push— send to OCIR - 🔹 Run:
docker run -d -p 8083:8083 --name api image:tag— launch - 🔹 Monitor:
docker ps,docker logs -f,docker stats— watch it live - 🔹 Debug:
docker exec -it container bash— go inside and investigate - 🔹 Stop:
docker stop→docker rm— graceful shutdown + cleanup - 🔹 Clean:
docker system prune -a— reclaim disk space monthly - 🔹 Compose:
docker compose up -d— run full ML systems with one command
Open a terminal right now. Type
docker images.
Then docker ps. Then try docker system df.
The best way to remember commands is to use them — not just read them.Practice the build → run → logs → exec → stop → rm cycle once today and it will feel natural forever. 🐳✨
Keep shipping, keep debugging, keep learning Docker! 🐼✨
Comments
Post a Comment