Essential Docker Commands Every Developer Should Know
Docker has become an indispensable part of modern software development, and knowing its command-line interface inside and out can save you hours of debugging and frustration. Whether you are containerizing your first application or managing production workloads, the Docker CLI provides the tools you need to build, ship, and run containers effectively. This guide covers the essential Docker commands organized by category, with detailed explanations of what each command does, when to use it, and common options that make your workflow more efficient. By mastering these commands, you will be able to handle the vast majority of Docker tasks you encounter in daily development work.
## Image Management Commands
The docker build command is one of the most frequently used commands in the Docker ecosystem. It reads a Dockerfile in your current directory and constructs a new image according to the instructions specified in that file. You use the lowercase t flag to tag the image with a name and optionally a version tag, which makes it easy to reference later when running containers or pushing to a registry. The build context, which is the set of files sent to the Docker daemon during the build process, defaults to the current directory but can be specified with a path argument. For larger projects, using a .dockerignore file to exclude unnecessary files from the build context significantly speeds up builds and reduces image size. Our guide on how to containerize a Node.js application walks through building production-ready images in detail.
The docker pull command downloads images from a registry such as Docker Hub or a private registry to your local machine. This is the command Docker implicitly runs behind the scenes when you try to run a container from an image you do not already have locally. However, explicitly pulling images is useful when you want to pre-fetch images before deploying, verify that a specific image tag exists, or download images for offline use. You can specify a particular tag after a colon, and if you omit the tag Docker defaults to latest. For organizations using private registries, you need to authenticate first using the docker login command before you can pull private images.
The docker push command uploads a locally built image to a remote registry, making it available for other team members or deployment systems. Before pushing, you must tag your image with the registry address, repository name, and optional tag. For example, pushing to Docker Hub requires a username prefix, while pushing to a private registry requires the full registry hostname. This command is essential for any team workflow because it enables continuous integration systems to pull the latest built images and deploy them to staging or production environments. Following Docker deployment best practices for production ensures your pushed images are optimized and secure.
The docker images command lists all images stored on your local machine, showing the repository name, tag, image ID, creation date, and size. This command helps you understand what images are taking up disk space and identify stale or unnecessary images that can be cleaned up. The dangling filter is particularly useful for finding images that are not tagged and serve no purpose, which are often leftover from intermediate build stages. You can also format the output using Go templates to display only the columns you care about, making it easier to script and parse.
The docker rmi command removes one or more images from your local storage. You can remove images by their ID, repository name and tag, or by using filters. Be aware that Docker prevents you from removing images that are currently in use by running containers unless you force removal. This command is most useful in cleanup scripts and when you need to free disk space after testing multiple image variants. When working with image digests for reproducibility, you can also remove specific digests while keeping tagged references to the same image.
## Container Management Commands
The docker run command creates and starts a new container from a specified image. This is arguably the most versatile Docker command because it supports dozens of flags that control every aspect of container behavior. The lowercase d flag runs the container in detached mode, meaning it runs in the background and returns control to your terminal. The lowercase p flag maps a port on your host machine to a port inside the container, which is essential for accessing web applications running inside containers. The name flag assigns a custom name to the container, making it easier to reference in subsequent commands instead of using auto-generated names. The env flag sets environment variables that the container can access at runtime, and the volume or v flag mounts host directories or named volumes into the container for persistent storage.
The docker ps command lists running containers by default, but adding the lowercase a flag shows all containers including stopped ones. The output includes the container ID, image name, command being executed, creation time, status, port mappings, and container name. This command is your primary tool for seeing what is currently running on your system. The format flag lets you customize the output, and the filter flag allows you to narrow results by status, label, network, or other attributes. When troubleshooting issues, docker ps is usually the first command you run to verify that your containers are actually running and to check their status and port mappings.
The docker stop command gracefully shuts down one or more running containers by sending a SIGTERM signal, followed by a SIGKILL signal if the container does not stop within a grace period, which defaults to ten seconds. Graceful shutdown is important because it gives applications time to finish processing in-flight requests, close database connections, and flush buffers. The docker kill command, by contrast, sends an immediate SIGKILL signal that terminates the container without any grace period. You should generally use stop in normal operations and reserve kill for situations where a container is unresponsive and needs to be terminated immediately.
The docker rm command removes stopped containers from your system. When a container stops, it is not automatically removed, and over time stopped containers can accumulate and consume disk space. The force flag allows you to remove a running container, combining stop and rm into a single operation. The volumes flag also removes any anonymous volumes associated with the container. A common cleanup pattern is to combine docker stop and docker rm when you need to recreate a container with different configuration, such as updated environment variables or different port mappings.
The docker exec command runs a new command inside an already running container. This is incredibly useful for debugging because it lets you shell into a container and inspect its filesystem, check running processes, verify environment variables, and test network connectivity. The interactive and tty flags, typically used together, provide an interactive terminal session inside the container. You can also run one-off commands without an interactive shell, such as checking a configuration file or running a diagnostic tool. This command is one of your most valuable debugging tools when things are not behaving as expected inside a container.
## Docker Compose Commands
The docker compose up command reads a compose YAML file and creates and starts all the services defined within it. This is the primary command for working with multi-container applications during local development. The detached flag runs all services in the background. The build flag forces a rebuild of images before starting services, which is useful when you have made changes to your application code or Dockerfiles. The scale flag lets you start multiple instances of a particular service, which is helpful for testing load balancing behavior. When comparing Docker Compose versus Kubernetes, Compose excels at local development simplicity while Kubernetes provides production-grade orchestration.
The docker compose down command stops and removes all containers, networks, and volumes created by the compose up command. The volumes flag additionally removes named volumes, which is useful for completely resetting your development environment. This command is the cleanest way to tear down a multi-container development environment, ensuring that no containers or network resources are left behind. Unlike individually stopping and removing containers, compose down understands the relationships defined in your compose file and cleans up everything as a unit.
The docker compose logs command streams the combined log output from all services defined in your compose file. You can follow the logs with the follow flag to see new output in real time, and filter by specific service names to focus on one service at a time. The timestamps flag adds timestamps to each log line, which is essential for correlating events across multiple services when debugging interactions between containers. This command is often more convenient than using docker logs on individual containers because it shows all service logs in a unified, color-coded stream.
The docker compose ps command lists the status of all services in your compose stack, showing which services are running, their container IDs, ports, and current state. This gives you a quick overview of your entire multi-container application without having to run docker ps and mentally map container names to services. When services have health checks defined, the compose ps output also shows the health status, making it easy to identify services that are up but unhealthy.
## Networking Commands
The docker network create command creates a new custom network that containers can attach to. By default, Docker provides a bridge network for basic container communication, but custom networks offer several advantages including automatic DNS resolution between containers, network isolation between different application stacks, and the ability to configure network drivers for specific use cases. When you use docker compose, it automatically creates a custom network for your services, which is why containers in a compose stack can reference each other by service name.
The docker network connect and docker network disconnect commands allow you to attach or detach a running container from a network. This is useful when you need to add a container to a new network without recreating it, or when troubleshooting network connectivity issues by testing whether a container can communicate on a different network. These commands are particularly handy for debugging because they let you dynamically change a container's network configuration while it is running, something that is not possible through the compose file alone.
The docker port command lists the port mappings for a specific container, showing which host ports are mapped to which container ports and the protocol used. This is a quick diagnostic tool when you are trying to access a service running inside a container but are not sure which ports are exposed or mapped correctly. It also shows whether ports are bound to specific interfaces or available on all interfaces, which is important for security configuration.
## Volume and Storage Commands
The docker volume create command creates a new named volume that persists independently of any container lifecycle. Named volumes are the recommended approach for persistent data storage in Docker because they are managed by Docker, easy to back up, and can be shared between containers. Unlike bind mounts, which directly map a host directory into a container, named volumes are stored in Docker's internal storage location and provide better performance and portability across different operating systems.
The docker volume ls command lists all Docker volumes on your system, including named volumes created explicitly and anonymous volumes created implicitly by container runs. The command shows volume names, driver types, and mount points, helping you understand what persistent storage exists on your system. When disk space is tight, reviewing your volumes helps identify orphaned volumes that are no longer associated with any container.
The docker volume rm command removes one or more volumes that are not currently in use by any container. Docker prevents removal of volumes that are attached to running or stopped containers, protecting your data from accidental deletion. Combining this with the dangling filter allows you to remove only volumes that are not referenced by any container, which is a safe cleanup operation for reclaiming disk space.
## System Cleanup Commands
The docker system df command shows how much disk space Docker is using across images, containers, volumes, and build cache. This high-level overview helps you understand where your disk space is going and decide what to clean up. It shows both the total size and the reclaimable amount, giving you a clear picture of how much space you could free with cleanup operations.
The docker system prune command is a powerful cleanup tool that removes all stopped containers, unused networks, dangling images, and build cache in one operation. The volumes flag extends this cleanup to include unused volumes, and the all flag removes all unused images rather than just dangling ones. This command is incredibly useful for reclaiming disk space, especially on development machines where you frequently build and test different image configurations. However, use it with caution because it permanently removes resources that you might need.
The docker image prune command specifically targets unused images, removing those that are not referenced by any running or stopped container. The all flag extends this to remove all unused images regardless of whether they have containers, and the filter flag lets you target specific conditions such as images older than a certain duration. This is a more targeted cleanup option than system prune when you want to be selective about what gets removed.
## Logging and Debugging Commands
The docker logs command fetches the standard output and standard error streams of a container, which is where most applications write their log messages. The follow flag streams logs in real time, similar to the tail command in Linux. The tail flag shows only the last specified number of lines, and the since flag filters logs to those generated after a specific timestamp. The timestamps flag adds timestamps to each log line, which is crucial for debugging timing-related issues. When running containers in detached mode, docker logs is your primary window into what the container is doing and any errors it might be encountering.
The docker inspect command provides detailed low-level information about any Docker object, including containers, images, volumes, and networks. It returns a JSON document containing the complete configuration, state, and metadata of the object. This is an invaluable debugging tool when you need to verify environment variables, check mount points, review networking configuration, or understand the exact state of a container. The format flag lets you extract specific fields from the JSON output, making it useful for scripting and automation.
The docker top command displays the running processes inside a container, similar to the Linux top command but scoped to a single container. This helps you verify that your application is running the expected processes, identify unexpected processes, and check resource consumption at the process level. It is a quick way to see what is happening inside a container without needing to exec into it.
The docker stats command shows a live stream of resource usage statistics for all running containers, including CPU percentage, memory usage, network input and output, and block input and output. This is essential for performance monitoring and capacity planning because it helps you identify containers that are consuming excessive resources or not performing as expected. When you need to monitor a single container, you can specify its name or ID to filter the output.
## Practical Debugging Workflows
When a containerized application is not behaving correctly, a systematic debugging workflow saves significant time compared to random troubleshooting. Start with docker ps to verify the container is running and check its status. If the container has exited, use docker ps with the all flag to see the exit code, which provides clues about the failure mode. Next, run docker logs to check the application output for error messages. If the logs do not reveal the issue, use docker inspect to verify environment variables, mount points, and network configuration match your expectations.
If the application is running but producing incorrect results, use docker exec to shell into the container and inspect the filesystem, check configuration files, and test commands manually. Verify that the correct version of your code is deployed by checking file timestamps and content. Test network connectivity from inside the container using tools like curl or wget to ensure the container can reach external services and other containers.
When dealing with resource-related issues, docker stats helps identify whether the container is hitting CPU or memory limits. Docker desktop users can also use the built-in dashboard for a visual representation of resource consumption. For persistent data issues, verify that volumes are correctly mounted and contain the expected data by inspecting the volume mount points through docker inspect.
Avoiding common Docker mistakes developers make prevents many debugging sessions from being necessary in the first place. Proper image layering, efficient Dockerfile construction, appropriate base image selection, and correct environment variable handling eliminate entire categories of problems that developers frequently encounter.
## Integrating Docker Commands into Your Development Workflow
The most effective way to internalize Docker commands is to incorporate them into your daily development routine. Use docker compose up at the start of each work session to spin up your entire development environment, including databases, caches, and message queues, ensuring consistency across team members. Use docker compose down and volume cleanup when switching between branches that require different database states.
Incorporate docker build into your pre-commit hooks or local CI to catch Dockerfile issues before they reach the shared pipeline. Use docker image prune regularly to prevent disk space from accumulating on your development machine. When onboarding new team members, having a well-documented set of Docker commands for common operations dramatically reduces the time it takes for them to become productive.
For teams using advanced deployment platforms, many of these commands become less critical for daily work because the platform handles container orchestration, networking, and scaling automatically. However, understanding what these commands do under the surface helps you diagnose issues more effectively and communicate with operations teams using precise terminology. Platforms like Deployxa Cloud v4.2.0 handle the complexity of running containers in production, but developers who understand Docker fundamentals can make better architectural decisions, write more efficient Dockerfiles, and debug issues faster when they do arise.