Skip to content

Docker Image Management

This chapter will provide an in-depth explanation of Docker image management, including core operations such as image acquisition, building, tagging, distribution, and optimization.

Image Concepts Review

Image Layered Structure

Docker images use a Union File System, composed of multiple read-only layers:

┌─────────────────────────────────────┐
│     Application layer (writable)    │  ← Container runtime writable layer
├─────────────────────────────────────┤
│     Layer 4: Application files     │  ← Read-only layer
├─────────────────────────────────────┤
│     Layer 3: Application deps      │  ← Read-only layer
├─────────────────────────────────────┤
│     Layer 2: Runtime environment   │  ← Read-only layer
├─────────────────────────────────────┤
│     Layer 1: Base OS              │  ← Read-only layer (Base Image)
└─────────────────────────────────────┘

Image Identifiers

Each image has a unique identifier:

bash
# Full format
[registry_host[:port]/]username/repository[:tag]

# Examples
docker.io/library/nginx:1.21.6          # Official image
docker.io/myuser/myapp:v1.0             # User image
registry.company.com:5000/team/app:latest # Private registry image

Image Acquisition Operations

Pull Images from Registries

bash
# Pull latest version
docker pull nginx

# Pull specific version
docker pull nginx:1.21.6

# Pull specific architecture image
docker pull --platform linux/amd64 nginx:latest

# Pull from private registry
docker pull registry.company.com:5000/myapp:v1.0

# Pull all tags
docker pull -a nginx

# View pull progress
docker pull nginx:latest

Search Images

bash
# Search official images
docker search nginx

# Limit search results
docker search --limit 10 nginx

# Show only official images
docker search --filter is-official=true nginx

# Filter by stars
docker search --filter stars=100 nginx

# Format output
docker search --format "table {{.Name}}\t{{.Description}}\t{{.Stars}}" nginx

Image Viewing Operations

List Local Images

bash
# List all images
docker images
docker image ls

# Show image digests
docker images --digests

# Show only image IDs
docker images -q

# Show all images (including intermediate layers)
docker images -a

# Custom output format
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

# Filter images
docker images --filter "dangling=true"      # Dangling images
docker images --filter "before=nginx:latest" # Created before specified image
docker images --filter "since=nginx:latest"  # Created after specified image
docker images --filter "reference=nginx:*"   # Match name pattern

View Image Details

bash
# View image detailed configuration
docker inspect nginx:latest

# Get specific information
docker inspect --format='{{.Config.Env}}' nginx:latest
docker inspect --format='{{.Architecture}}' nginx:latest
docker inspect --format='{{.Size}}' nginx:latest

# View image history
docker history nginx:latest

# Show detailed history
docker history --no-trunc nginx:latest

# View image layer information
docker image inspect --format='{{json .RootFS.Layers}}' nginx:latest

Image Tagging Operations

Tag Images

bash
# Add new tag to image
docker tag nginx:latest myregistry/nginx:v1.0

# Tag as different versions
docker tag myapp:latest myapp:v1.0
docker tag myapp:latest myapp:stable

# Tag to private registry
docker tag myapp:latest registry.company.com:5000/myapp:v1.0

# View tagging results
docker images myapp

Rename Images

bash
# Docker has no direct rename command, use tag and delete
# 1. Create new tag
docker tag old-name:tag new-name:tag

# 2. Delete old tag
docker rmi old-name:tag

# Example: rename image
docker tag myapp:old myapp:new
docker rmi myapp:old

Image Building Operations

Build Using Dockerfile

bash
# Basic build command
docker build -t myapp:v1.0 .

# Specify Dockerfile path
docker build -f /path/to/Dockerfile -t myapp:v1.0 .

# Specify build context
docker build -t myapp:v1.0 /path/to/context

# Build from URL
docker build -t myapp:v1.0 https://github.com/user/repo.git

# Build from standard input
docker build -t myapp:v1.0 - < Dockerfile

# Build without cache
docker build --no-cache -t myapp:v1.0 .

# Specify build arguments
docker build --build-arg VERSION=1.0 -t myapp:v1.0 .

# Specify target stage (multi-stage build)
docker build --target production -t myapp:v1.0 .

# Set memory limit
docker build -m 1g -t myapp:v1.0 .

Build Example

Create a simple Node.js application image:

dockerfile
# Dockerfile
FROM node:16-alpine

# Set working directory
WORKDIR /app

# Copy package.json
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Expose port
EXPOSE 3000

# Set startup command
CMD ["npm", "start"]
bash
# Build image
docker build -t mynode-app:v1.0 .

# Run container for testing
docker run -d -p 3000:3000 --name test-app mynode-app:v1.0

Image Import/Export

Export Images

bash
# Export single image
docker save nginx:latest -o nginx.tar
docker save nginx:latest > nginx.tar

# Export multiple images
docker save nginx:latest ubuntu:20.04 -o images.tar

# Compressed export
docker save nginx:latest | gzip > nginx.tar.gz

# View export file size
ls -lh nginx.tar

Import Images

bash
# Import image
docker load -i nginx.tar
docker load < nginx.tar

# Import compressed image
gunzip -c nginx.tar.gz | docker load

# Verify import result
docker images nginx

Commit Container to Image

bash
# Create image from running container
docker commit container_name new_image:tag

# Add commit message
docker commit -m "Added new feature" -a "Author Name" container_name new_image:tag

# Specify configuration changes
docker commit --change='CMD ["nginx", "-g", "daemon off;"]' container_name new_image:tag

# Commit after pausing container
docker commit --pause=true container_name new_image:tag

Image Deletion Operations

Delete Images

bash
# Delete single image
docker rmi nginx:latest

# Delete multiple images
docker rmi nginx:latest ubuntu:20.04

# Force delete image
docker rmi -f nginx:latest

# Delete all dangling images
docker image prune

# Delete all unused images
docker image prune -a

# Delete images older than specified time
docker image prune --filter "until=24h"

# Batch delete images
docker rmi $(docker images -q)
docker rmi $(docker images --filter "dangling=true" -q)

Clean Up Image Space

bash
# View Docker disk usage
docker system df

# Detailed view of disk usage
docker system df -v

# Clean all unused resources
docker system prune

# Clean all resources (including unused images)
docker system prune -a

# Clean resources older than specified time
docker system prune --filter "until=72h"

# Force cleanup (no confirmation prompt)
docker system prune -f

Image Registry Operations

Login and Authentication

bash
# Login to Docker Hub
docker login

# Login to private registry
docker login registry.company.com:5000

# Login with username and password
docker login -u username -p password registry.company.com:5000

# Read password from file
cat password.txt | docker login -u username --password-stdin

# View login information
cat ~/.docker/config.json

# Logout
docker logout
docker logout registry.company.com:5000

Push Images

bash
# Push to Docker Hub
docker push myuser/myapp:v1.0

# Push to private registry
docker push registry.company.com:5000/myapp:v1.0

# Push all tags
docker push -a myuser/myapp

# View push progress
docker push myuser/myapp:v1.0

Private Registry Configuration

bash
# Run local registry
docker run -d -p 5000:5000 --name registry registry:2

# Push to local registry
docker tag myapp:v1.0 localhost:5000/myapp:v1.0
docker push localhost:5000/myapp:v1.0

# Pull from local registry
docker pull localhost:5000/myapp:v1.0

# Configure insecure registry (/etc/docker/daemon.json)
{
  "insecure-registries": ["registry.company.com:5000"]
}

Image Optimization Techniques

Reduce Image Size

dockerfile
# 1. Use multi-stage builds
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]

# 2. Use .dockerignore file
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
coverage
.nyc_output

# 3. Combine RUN instructions
RUN apt-get update && \
    apt-get install -y curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# 4. Use lightweight base images
FROM alpine:3.14
FROM node:16-alpine
FROM python:3.9-slim

Image Security Optimization

dockerfile
# 1. Use non-root user
FROM node:16-alpine
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs

# 2. Install only necessary packages
RUN apk add --no-cache curl

# 3. Set read-only root filesystem
FROM alpine:3.14
RUN adduser -D -s /bin/sh appuser
USER appuser
# Use --read-only flag at runtime

# 4. Scan image for vulnerabilities
docker scan myapp:v1.0

Build Cache Optimization

dockerfile
# 1. Optimize layer order (layers that change less go first)
FROM node:16-alpine
WORKDIR /app

# Copy dependency files first
COPY package*.json ./
RUN npm ci

# Copy application code later
COPY . .
RUN npm run build

# 2. Use BuildKit cache mounts
# syntax=docker/dockerfile:1
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci

# 3. Use external cache
docker buildx build --cache-from type=registry,ref=myapp:cache \
                   --cache-to type=registry,ref=myapp:cache \
                   -t myapp:v1.0 .

Image Analysis Tools

Analyze Images Using dive

bash
# Install dive
curl -OL https://github.com/wagoodman/dive/releases/download/v0.10.0/dive_0.10.0_linux_amd64.deb
sudo apt install ./dive_0.10.0_linux_amd64.deb

# Analyze image
dive nginx:latest

# Analyze locally built image
dive myapp:v1.0

Optimize Images Using docker-slim

bash
# Install docker-slim
curl -sL https://raw.githubusercontent.com/docker-slim/docker-slim/master/scripts/install-dockerslim.sh | sudo -E bash -

# Optimize image
docker-slim build --target nginx:latest --tag nginx:slim

# View optimization results
docker images nginx

Practice Exercises

Exercise 1: Build Python Web Application Image

dockerfile
# Dockerfile
FROM python:3.9-slim

# Set working directory
WORKDIR /app

# Install system dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends gcc && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Copy dependency files
COPY requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Create non-root user
RUN useradd --create-home --shell /bin/bash app && \
    chown -R app:app /app
USER app

# Expose port
EXPOSE 8000

# Startup command
CMD ["python", "app.py"]
bash
# Build image
docker build -t python-web:v1.0 .

# Run test
docker run -d -p 8000:8000 --name python-app python-web:v1.0

# View image size
docker images python-web:v1.0

Exercise 2: Multi-Stage Build Go Application

dockerfile
# Multi-stage build Dockerfile
# Build stage
FROM golang:1.19-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Runtime stage
FROM alpine:3.16

RUN apk --no-cache add ca-certificates
WORKDIR /root/

# Copy binary from build stage
COPY --from=builder /app/main .

# Create non-root user
RUN adduser -D -s /bin/sh appuser
USER appuser

EXPOSE 8080
CMD ["./main"]
bash
# Build image
docker build -t go-app:v1.0 .

# Compare image sizes
docker images go-app:v1.0
docker images golang:1.19-alpine

Chapter Summary

This chapter comprehensively introduced various aspects of Docker image management:

Key Points:

  • Image acquisition: Pull, search, import images
  • Image viewing: List, inspect, analyze images
  • Image building: Build custom images using Dockerfile
  • Image tagging: Version management and naming conventions
  • Image distribution: Push to registries and private registry management
  • Image optimization: Reduce size, improve security, optimize builds

Best Practices:

  • Use specific image tags instead of latest
  • Regularly clean up unused images
  • Use multi-stage builds to reduce image size
  • Follow image security best practices
  • Reasonably utilize build cache

In the next chapter, we will learn about Docker data management, including volumes, bind mounts, and data persistence strategies.

Further Reading

Content is for learning and research only.