Introduction to Docker CLI
In our previous lectures, we explored container concepts and Docker's architecture. Today, we'll focus on the practical side of Docker - the commands you'll use daily to manage containers, images, networks, and volumes. Understanding these commands is essential for effective Docker usage.
The Docker Command Line Interface (CLI) is the primary way developers interact with Docker. It provides a rich set of commands for managing all aspects of containers and related resources. Think of the Docker CLI as a powerful remote control for your container infrastructure - with the right commands, you can control every aspect of your containerized applications.
Getting Help with Docker Commands
Before diving into specific commands, let's explore how to get help when using Docker. The Docker CLI has built-in documentation that you can access right from your terminal.
Command Help
# Get a list of all Docker commands
docker
# General help
docker --help
# Help on a specific command
docker run --help
docker container --help
Using the help commands is like having a Docker manual at your fingertips. It's a good practice to check the help for commands you're not familiar with, or to discover options for commands you use regularly.
Command Structure
Docker commands follow a consistent structure:
docker [command] [subcommand] [options] [arguments]
For example:
docker container run --name mycontainer -p 8080:80 -d nginx
In this command:
dockeris the base commandcontaineris the management commandrunis the subcommand--name mycontainerand-p 8080:80are options-dis a flag (option without a value)nginxis an argument (the image to use)
Docker supports both a newer, more explicit management command structure (docker container run) and a legacy shorthand structure (docker run). Both work the same, but we'll primarily use the newer structure in this lecture for clarity.
Container Lifecycle Commands
Containers go through a lifecycle from creation to removal. Understanding how to manage this lifecycle is fundamental to working with Docker.
Creating and Running Containers
The docker container run command creates and starts a container in a single operation:
# Basic run command
docker container run nginx
# Run with a name
docker container run --name webserver nginx
# Run in detached mode (background)
docker container run -d nginx
# Run with port mapping
docker container run -p 8080:80 nginx
# Run with environment variables
docker container run -e MYSQL_ROOT_PASSWORD=password mysql
# Run and remove when stopped
docker container run --rm nginx
# Run interactively with terminal
docker container run -it ubuntu bash
Running a container is like starting a virtual computer with a specific application already installed. The run command has numerous options that allow you to configure almost every aspect of the container environment.
Common Run Options
| Option | Description | Example |
|---|---|---|
-d, --detach |
Run container in background | docker container run -d nginx |
-p, --publish |
Map container port to host port | docker container run -p 8080:80 nginx |
-v, --volume |
Bind mount a volume | docker container run -v /host/dir:/container/dir nginx |
-e, --env |
Set environment variables | docker container run -e VARIABLE=value nginx |
--name |
Assign a name to the container | docker container run --name webserver nginx |
-it |
Interactive with terminal | docker container run -it ubuntu bash |
--rm |
Remove container when it exits | docker container run --rm nginx |
--network |
Connect to a network | docker container run --network my-network nginx |
Viewing Containers
# List running containers
docker container ls
# or
docker ps
# List all containers (including stopped)
docker container ls -a
# or
docker ps -a
# Show the latest created container
docker container ls -l
# Show n last created containers
docker container ls -n 5
# Show container sizes
docker container ls -s
Listing containers is like checking which applications are currently running or installed on your system. This is often your starting point for managing running containers.
Managing Container State
# Stop a running container
docker container stop container_id_or_name
# Start a stopped container
docker container start container_id_or_name
# Restart a container
docker container restart container_id_or_name
# Pause a container (freeze its processes)
docker container pause container_id_or_name
# Unpause a container
docker container unpause container_id_or_name
# Kill a container (forceful stop)
docker container kill container_id_or_name
These commands let you control the state of your containers, similar to how you might start, stop, or restart applications on your computer. The difference is that Docker maintains the container's filesystem state between stops and starts, allowing you to resume exactly where you left off.
Removing Containers
# Remove a stopped container
docker container rm container_id_or_name
# Force remove a running container
docker container rm -f container_id_or_name
# Remove all stopped containers
docker container prune
Removing containers is like uninstalling applications, except that in Docker, you can have multiple "installations" (containers) of the same application (image). Removing a container permanently deletes its writable layer, but doesn't affect the underlying image.
Interacting with Running Containers
Once containers are running, you'll often need to interact with them to check logs, execute commands, or monitor their status.
Viewing Container Logs
# View container logs
docker container logs container_id_or_name
# Follow log output (like tail -f)
docker container logs -f container_id_or_name
# Show last n lines
docker container logs --tail 100 container_id_or_name
# Show logs with timestamps
docker container logs -t container_id_or_name
Container logs capture stdout and stderr from the container's main process. This is like reading application log files, but Docker consolidates and streams them for you automatically.
Executing Commands in Containers
# Execute a command in a running container
docker container exec container_id_or_name command
# Execute interactively
docker container exec -it container_id_or_name bash
# Execute as a specific user
docker container exec -u username container_id_or_name command
# Execute with environment variables
docker container exec -e VAR=value container_id_or_name command
The exec command lets you run additional processes inside a running container. This is like SSH-ing into a remote server to run commands, but for containers. It's particularly useful for debugging, maintenance, or adding functionality to existing containers.
Container Inspection and Monitoring
# View detailed container information
docker container inspect container_id_or_name
# Format specific information
docker container inspect -f '{{.NetworkSettings.IPAddress}}' container_id_or_name
# Show container resource usage statistics
docker container stats
# Show running processes in a container
docker container top container_id_or_name
These commands give you visibility into what's happening inside your containers, similar to system monitoring tools like Task Manager (Windows) or Activity Monitor (macOS). The inspect command in particular provides a wealth of information about a container's configuration and state.
Copying Files Between Container and Host
# Copy from host to container
docker container cp file.txt container_id_or_name:/path/in/container/
# Copy from container to host
docker container cp container_id_or_name:/path/in/container/file.txt ./
# Copy directory
docker container cp directory/ container_id_or_name:/path/in/container/
The cp command works like a secure copy (scp) between your local system and the container. It's useful for transferring configuration files, getting logs, or updating content without rebuilding the container.
Image Management Commands
Docker images are the blueprints for containers. Managing them effectively is key to a streamlined Docker workflow.
Finding and Pulling Images
# Search for images on Docker Hub
docker search nginx
# Pull an image
docker image pull nginx
# Pull a specific version (tag)
docker image pull nginx:1.19
# Pull from a different registry
docker image pull registry.example.com/myimage:tag
Pulling images is like downloading applications from an app store. Docker Hub is the default public registry, but you can also use private registries for proprietary or internal images.
Listing and Inspecting Images
# List images
docker image ls
# List all images (including intermediates)
docker image ls -a
# List images with size
docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.Size}}"
# List dangling images (untagged)
docker image ls --filter dangling=true
# Inspect image details
docker image inspect nginx
# View image layers
docker image history nginx
These commands help you manage your local image inventory, similar to how you might review installed software on your system. The history command is particularly useful for understanding how an image was built and what each layer contributes.
Building Images
# Build an image from a Dockerfile in current directory
docker image build -t myapp:1.0 .
# Build with build arguments
docker image build --build-arg VERSION=1.0 -t myapp:1.0 .
# Build from a specific Dockerfile
docker image build -f Dockerfile.prod -t myapp:prod .
# Build without using cache
docker image build --no-cache -t myapp:1.0 .
Building images is like compiling software from source code. The Dockerfile provides the "recipe," and the build command executes it to create a ready-to-use image. We'll cover Dockerfile syntax in more detail in a future lecture.
Tagging and Pushing Images
# Tag an image
docker image tag myapp:1.0 myapp:latest
# Tag for a registry
docker image tag myapp:1.0 username/myapp:1.0
# Push to a registry
docker image push username/myapp:1.0
# Push to a private registry
docker image push registry.example.com/myapp:1.0
Tagging and pushing images is like versioning and publishing software. Tags help you identify specific versions or variants of an image, while pushing makes images available to others through a registry.
Removing Images
# Remove an image
docker image rm nginx
# Remove by ID
docker image rm image_id
# Force remove an image
docker image rm -f nginx
# Remove all unused images
docker image prune
# Remove all unused images, not just dangling ones
docker image prune -a
Removing images frees up disk space, similar to uninstalling unused applications. Docker's layer system means that removing one image often doesn't delete as much data as you might expect, since layers are shared between images.
Saving and Loading Images
# Save an image to a tar file
docker image save -o nginx.tar nginx
# Load an image from a tar file
docker image load -i nginx.tar
# Export a container's filesystem as a tar file
docker container export container_id > container.tar
# Import a container filesystem to create an image
docker image import container.tar myimage:latest
These commands allow you to transport Docker images without a registry, similar to exporting and importing applications. This is useful for air-gapped environments, backup purposes, or sharing images via physical media.
Network Management Commands
Docker networking enables communication between containers and with the outside world. The following commands help you manage Docker networks.
Listing and Creating Networks
# List networks
docker network ls
# Create a network
docker network create mynetwork
# Create a network with subnet
docker network create --subnet=192.168.0.0/16 mynetwork
# Create an overlay network (for Swarm)
docker network create -d overlay mynetwork
Creating Docker networks is like setting up virtual LANs in a data center. Each network provides isolation while allowing connected containers to communicate.
Connecting Containers to Networks
# Run a container with a specific network
docker container run --network=mynetwork nginx
# Connect a running container to a network
docker network connect mynetwork container_id_or_name
# Disconnect a container from a network
docker network disconnect mynetwork container_id_or_name
These commands are like plugging devices into different network switches. Containers can be connected to multiple networks simultaneously, giving you flexibility in designing your application's network topology.
Inspecting Networks
# View network details
docker network inspect mynetwork
# List containers in a network
docker network inspect -f '{{range .Containers}}{{.Name}} {{end}}' mynetwork
Network inspection helps you understand the current network configuration and connectivity, similar to using network monitoring tools to view connected devices and IP assignments.
Removing Networks
# Remove a network
docker network rm mynetwork
# Remove all unused networks
docker network prune
Cleaning up unused networks helps maintain a tidy Docker environment, just as you might remove unused cables and switches in a physical network.
Volume Management Commands
Volumes provide persistent storage for container data. These commands help you manage Docker volumes.
Creating and Listing Volumes
# Create a volume
docker volume create myvolume
# List volumes
docker volume ls
# Filter volumes by name
docker volume ls -f name=my*
Creating volumes is like adding external storage devices to your system. Volumes persist data independently from containers, ensuring that your data survives even when containers are removed.
Using Volumes with Containers
# Run a container with a volume
docker container run -v myvolume:/data nginx
# Use a host directory as a volume (bind mount)
docker container run -v /host/path:/container/path nginx
# Use a temporary in-memory filesystem (tmpfs)
docker container run --tmpfs /tmp nginx
These commands connect storage to your containers, similar to mounting drives or network shares in a traditional operating system. Docker supports several types of mounts, each with different characteristics.
Inspecting Volumes
# View volume details
docker volume inspect myvolume
# Get the mount path of a volume
docker volume inspect -f '{{.Mountpoint}}' myvolume
Volume inspection helps you understand where and how volume data is stored on the host system, similar to checking disk properties in an operating system.
Removing Volumes
# Remove a volume
docker volume rm myvolume
# Remove all unused volumes
docker volume prune
Removing volumes permanently deletes the stored data, similar to formatting a hard drive. Be cautious when using these commands to avoid data loss.
System Management Commands
Docker provides several commands for managing the Docker system as a whole, including disk usage, events, and information.
System Information
# View Docker system information
docker system info
# or
docker info
# Show Docker version
docker version
# Check if Docker daemon is running
docker system ping
These commands provide insights into your Docker installation, similar to checking system information in an operating system. They're useful for troubleshooting and understanding your environment.
Disk Usage
# Show Docker disk usage
docker system df
# Show detailed disk usage
docker system df -v
Monitoring disk usage helps you manage resources effectively, just as you might use disk space analyzers in a traditional system.
Events and Monitoring
# Stream Docker events
docker system events
# Filter events by type
docker system events --filter type=container
# Show events in a time window
docker system events --since '2023-01-01'
The events command provides a real-time feed of what's happening in your Docker environment, similar to monitoring system logs or events in an operating system.
Pruning Resources
# Remove unused data (containers, networks, images, volumes)
docker system prune
# Include volumes in prune
docker system prune -a --volumes
# Prune with filter
docker system prune --filter "until=24h"
System pruning is like running a cleanup utility to remove temporary files and unused applications, freeing up disk space and keeping your environment tidy.
Practical Command Examples
Let's explore some practical examples that combine multiple Docker commands to accomplish common tasks.
Running a Web Server with Persistent Content
# Create a volume for web content
docker volume create web_content
# Run Nginx with the volume
docker container run -d --name webserver -p 8080:80 -v web_content:/usr/share/nginx/html nginx
# Copy content to the container
echo "<h1>Hello from Docker</h1>" > index.html
docker cp index.html webserver:/usr/share/nginx/html/
# View the website at http://localhost:8080
# Stop and remove the container
docker container stop webserver
docker container rm webserver
# Run a new container with the same volume
docker container run -d --name webserver2 -p 8080:80 -v web_content:/usr/share/nginx/html nginx
# The content persists!
This example demonstrates persistent storage with volumes. Even when the original container is removed, the data survives and can be accessed by a new container.
Creating a Multi-Container Application
# Create a network for the application
docker network create myapp
# Run a database container
docker container run -d --name db \
--network myapp \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=myapp \
-e MYSQL_PASSWORD=myapp \
mysql:5.7
# Run a web application container
docker container run -d --name web \
--network myapp \
-p 8080:80 \
-e DB_HOST=db \
-e DB_USER=myapp \
-e DB_PASSWORD=myapp \
-e DB_NAME=myapp \
mywebapp:latest
# Verify containers are running
docker container ls
# Check logs of the web app
docker container logs web
This example shows how to create a simple multi-container application with a web server and database, connected via a custom network. The containers can communicate using container names as hostnames.
Building and Pushing a Custom Image
# Create a Dockerfile
echo 'FROM nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80' > Dockerfile
# Create content
echo '<h1>My Custom Image</h1>' > index.html
# Build the image
docker image build -t myorg/custom-nginx:1.0 .
# Test the image
docker container run -d -p 8080:80 myorg/custom-nginx:1.0
# Tag for a different registry
docker image tag myorg/custom-nginx:1.0 registry.example.com/myorg/custom-nginx:1.0
# Push to registry (if authorized)
docker image push myorg/custom-nginx:1.0
This example demonstrates the process of building, testing, and publishing a custom Docker image. This workflow is common in CI/CD pipelines for containerized applications.
Debugging a Container Issue
# Start a container that has an issue
docker container run -d --name problematic -p 8080:80 nginx
# Check if it's running
docker container ls
docker container ls -a # If it stopped
# View logs
docker container logs problematic
# Get more details
docker container inspect problematic
# Execute commands inside for investigation
docker container exec -it problematic bash
# Inside container: check processes, configuration, files
ps aux
cat /etc/nginx/nginx.conf
ls -la /usr/share/nginx/html/
# Exit the container
exit
This example shows a typical debugging workflow for container issues. The ability to inspect, view logs, and execute commands inside a container provides powerful troubleshooting capabilities.
Command Patterns and Best Practices
Creating Efficient Commands
- Use short container IDs or names for brevity
- Combine related operations when possible
- Use appropriate flags to reduce verbosity (e.g.,
-qfor quiet output) - Leverage command formatting for easier parsing
# Instead of:
docker container ls -a
docker container rm container_id
# Use:
docker container rm $(docker container ls -aq)
Using Command Output
Many Docker commands can be combined using command substitution or piping:
# Get the IP address of a container
docker container inspect -f '{{.NetworkSettings.IPAddress}}' container_name
# Remove all containers with a specific status
docker container rm $(docker container ls -q -f status=exited)
# Find the largest images
docker image ls --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -hr | head -n 5
Creating Aliases for Common Commands
For frequently used commands, create aliases in your shell:
# Bash aliases (add to ~/.bashrc or ~/.bash_aliases)
alias dps='docker container ls'
alias dpsa='docker container ls -a'
alias drm='docker container rm'
alias dimg='docker image ls'
alias drun='docker container run -d'
alias dexec='docker container exec -it'
Docker Command Documentation
Always refer to the official Docker documentation for the most up-to-date information on commands and options. The Docker CLI is regularly updated with new features and improvements.
Conclusion
Today we've explored the essential Docker commands for managing containers, images, networks, and volumes. These commands form the foundation of your day-to-day interaction with Docker.
Remember that Docker commands are like tools in a toolbox - knowing which tool to use for each job makes you more effective. With practice, these commands will become second nature, allowing you to focus on building and running your applications rather than managing the container infrastructure.
In our next lecture, we'll dive deeper into Dockerfiles and the process of building custom images for your applications.
Practice Activities
Activity 1: Container Basics
Experiment with running, managing, and inspecting containers:
- Run an Nginx container in detached mode with port 8080 mapped to container port 80
- Verify the container is running and check its logs
- Create a simple HTML file and copy it into the container
- Verify the new content is accessible on http://localhost:8080
- Stop and remove the container
Activity 2: Working with Images
Practice image management commands:
- Pull the official Node.js, Python, and Redis images
- List all images and note their sizes
- Inspect the Node.js image and identify its environment variables
- Create a tag for the Node.js image with your username
- Remove the Python image
Activity 3: Networking Containers
Create a simple multi-container application:
- Create a custom bridge network
- Run a Redis container on this network
- Run an Alpine container with an interactive shell on the same network
- From the Alpine container, ping the Redis container by name
- Disconnect the Alpine container from the network and try to ping again
- Clean up all containers and the network
Activity 4: Data Persistence with Volumes
Explore volume management for data persistence:
- Create a named volume
- Run a MySQL container using this volume for data storage
- Connect to the MySQL container and create a database and table
- Stop and remove the container
- Run a new MySQL container using the same volume
- Verify that your database and table still exist
- Clean up all resources
Challenge: Container Orchestration Script
Create a shell script that automates the deployment of a multi-container application:
- The script should create necessary networks and volumes
- It should run at least three containers (e.g., web server, application server, database)
- Configure the containers to communicate with each other
- Include error handling and cleanup on failure
- Add a function to tear down the entire application
This challenge will test your understanding of Docker commands and how they fit together in a real-world scenario.
Additional Resources
Official Documentation
- Docker CLI Documentation
- Docker Run Reference
- Docker Storage Documentation
- Docker Network Documentation
Cheat Sheets
Learning Resources
Books
- "Docker Deep Dive" by Nigel Poulton
- "Docker in Action" by Jeff Nickoloff and Stephen Kuenzli
- "Docker: Up & Running" by Sean P. Kane and Karl Matthias