Efficient Docker image and container management is fundamental to maintaining a healthy container environment. Docker images accumulate on hosts — old base images, build cache layers, and unused intermediate images can consume tens of gigabytes of disk space if not managed regularly. Understanding the Docker image layer model is key: images consist of read-only layers stacked on each other, and each RUN, COPY, and ADD instruction in a Dockerfile creates a new layer. Containers add a thin writable layer on top of the image layers. This guide covers the essential Docker image and container management commands on RHEL 9: listing, inspecting, tagging, pushing/pulling images, managing container lifecycle, and cleaning up disk space.

Prerequisites

  • Docker Engine installed on RHEL 9

Step 1 — Image Management

# List all local images
docker images
docker images --format "table {{.Repository}}t{{.Tag}}t{{.Size}}"

# Pull an image
docker pull nginx:1.27-alpine

# Tag an image for a registry
docker tag nginx:1.27-alpine registry.example.com/myteam/nginx:1.27-alpine

# Push to registry
docker push registry.example.com/myteam/nginx:1.27-alpine

# Inspect image metadata and layers
docker inspect nginx:alpine
docker history nginx:alpine  # Show each layer and its size

# Search Docker Hub
docker search postgres

Step 2 — Container Lifecycle Management

# Create (without starting)
docker create --name mycontainer nginx:alpine

# Start/stop/restart
docker start mycontainer
docker stop mycontainer
docker restart mycontainer

# Run one-off command in a new container (removed after exit)
docker run --rm alpine echo "Hello from container"

# Interactive container for debugging
docker run -it --rm alpine /bin/sh

# List containers (running and stopped)
docker ps            # Running only
docker ps -a         # All containers
docker ps -a --format "table {{.Names}}t{{.Status}}t{{.Image}}"

Step 3 — Container Inspection and Debugging

# View container logs
docker logs mycontainer
docker logs -f mycontainer  # Follow
docker logs --tail 100 mycontainer

# Execute a command inside a running container
docker exec -it mycontainer /bin/sh
docker exec mycontainer cat /etc/nginx/nginx.conf

# Copy files to/from containers
docker cp mycontainer:/etc/nginx/nginx.conf ./nginx.conf
docker cp ./config.conf mycontainer:/etc/nginx/nginx.conf

# View resource usage
docker stats                   # Real-time CPU/memory/network stats
docker stats --no-stream       # One-time snapshot

Step 4 — Clean Up Disk Space

# Check Docker disk usage
docker system df

# Remove stopped containers
docker container prune -f

# Remove unused images (not referenced by any container)
docker image prune -f

# Remove all unused images (including tagged ones with no running containers)
docker image prune -a -f

# Remove unused volumes
docker volume prune -f

# Remove everything unused at once (containers, networks, images, build cache)
docker system prune -f
docker system prune -a -f  # Also removes all unused images (more aggressive)

Step 5 — Set Resource Limits on Containers

# Limit CPU and memory (prevent a single container from consuming all resources)
docker run -d 
    --name myapp 
    --memory="512m"          # Maximum memory
    --memory-swap="512m"     # Disable swap (same as memory = swap disabled)
    --cpus="1.5"             # Use at most 1.5 CPU cores
    myapp:latest

# Verify limits
docker inspect myapp | grep -E "Memory|Cpu"

Conclusion

Regular Docker image and container cleanup on RHEL 9 prevents disk exhaustion, which is a common operational issue on long-running Docker hosts. Implement a scheduled docker system prune -f in cron (weekly is typical) to remove stopped containers and dangling images automatically. Setting memory limits on all containers is equally important — without limits, a memory leak in any container can consume all available RAM and cause the kernel’s OOM killer to terminate other containers or system processes.

Next steps: How to Build Docker Images on RHEL 9, How to Set Up a Private Docker Registry on RHEL 9, and How to Configure Docker Networking on RHEL 9.