What is Docker CLI (Command Line Interface)?
Docker CLI tool is a command line application used to interact with the dockerd
daemon. The dockerd
daemon is the process that manages containers and handles all the commands sent from the CLI by exposing an API endpoint. So both dockerd
and Docker CLI pieces are needed for docker
to work. The following illustration depicts the overall Docker architecture:

In this entry you will go through the basics of the Docker CLI tool used to interface with Docker Engine, its key features, how to install and operate it, how to configure it, and how it relates to Docker Compose and Docker APIs.
Docker CLI features
The Docker CLI includes several useful features. It handles standard UNIX-style arguments, and in many cases, it offers both short and long forms.
For example, the flags -H, --host
are both for specifying the host to connect. It accepts environment variables (which weâll explain in detail later on), and it can also accept configuration from a file (config.json) so that admins can limit the passing of flags explicitly.
The âhelp
flag is nice, but it could be better (I would have liked to see more comprehensive documentation similar to that offered by the Git toolset). Most of the reference material can be found on the official documentation site.
There is an option to run the tool with experimental features for testing purposes by exporting the following env variable:
export DOCKER_CLI_EXPERIMENTAL=enabledCode language: JavaScript (javascript)
Finally, it also allows the tool to be extended using plugins. You will need to follow specific instructions to set up out-of-process extensions that the CLI tool can use (such as registering new commands).
You can check this
gist code of a sample plugin
example for adding a new command to the CLI that displays the Docker changelog for the installed version and know more about using plugins.
Installation and configuration
As with all software, you have to install it before you can use it. Docker CLI is written in the Go programming language, so it’s quite portable as a tool.
The dockerd daemon, which is responsible for handling the CLI requests, can run on most popular platforms (including Windows, Linux, and Mac with ARM/x86_64 /amd64 CPUs). You can find a list of platforms that support Docker
on this page
.
Installation
The Docker CLI can be installed as a desktop application (called Docker Desktop) or by using the command line. Note that commercial use of Docker Desktop in larger enterprises requires a paid subscription.
The
Get Docker
page provides instructions for installing Docker Desktop on your computer. Meanwhile, installing the Docker CLI requires you to run a bunch of commands. If you use Ubuntu, for example, you first need to ensure that your apt repository packages are up to date with the latest ca-certificates and gnupg:
$ sudo apt update
$ sudo apt install ca-certificates curl gnupg lsb-release
Note that you can use either curl or wget to download the gpg keys:
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpgCode language: JavaScript (javascript)
The following command updates the /etc/apt/sources.list.d/docker.list, adding a new repository for the Docker distribution and using the lsb_release tool for printing the right Linux distribution name:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Code language: PHP (php)
Now that the sources are configured, these last two commands are used to install the Docker CLI, dockerd, and docker-compose tools:
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
You can also install Docker using the installation script, which requires fewer steps. Just make sure that you make it executable before running it:
$ sudo apt update
$ sudo apt install ca-certificates curl gnupg lsb-release
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo chmod +x get-docker.sh
$ sudo sh ./get-docker.sh --dry-runCode language: JavaScript (javascript)
When all of these steps are done, you can check to see if everything is alright by printing the docker version:
$ docker version
Client:
Cloud integration: v1.0.22
Version: 20.10.13
API version: 1.41
Go version: go1.16.15
Git commit: a224086
â¦
Basic Interactivity
You can use the docker to issue commands and get information about the available list of options.
For example, to get the list of options for the docker image command, run:
$ docker image
Usage: docker image COMMAND
Manage images
Commands:
build Build an image from a Dockerfile
history Show the history of an image
â¦Code language: JavaScript (javascript)
Use docker âhelp to get a detailed list of available options for a subcommand. For example:
$ docker image build --help
Usage: docker image build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
â¦Code language: JavaScript (javascript)
Running erroneous commands will stop the execution of the task and print an associated error:
$ docker image build -t
flag needs an argument: 't' in -t
See 'docker image build --help'.Code language: JavaScript (javascript)
When you first install Docker, you may need to log into a registry to push or pull images. You can do that with the docker login command:
$ docker login registry.gitlab.com
Authenticating with existing credentials...
Login SucceededCode language: JavaScript (javascript)
There are a lot of available commands in Docker with further subcommands and flags. Most of the time, though, you will be using just a few of them. We will explore those in detail later in this tutorial.
Environment Variables
The Docker CLI runs on an execution context and can be configured with environment variables. These variables are used to configure connection parameters and access credentials. There arenât many of them, but itâs important to know what they do. Here are some of the most important ones:
DOCKER_HOST
: This is used to change the host that the CLI tool connects to. It needs to be a valid connection string. The different types of connection strings can be located in
this section of the code
. For example, tcp://1.2.3.4:5678 and unix:///path are valid connection strings.
DOCKER_CONTEXT:
This is used to specify the default Docker context to use. You can use Docker contexts to easily switch back to different hosts. For example, here is a list of available contexts:
$ docker context list
NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock https://127.0.0.1:55093 (default) swarmCode language: PHP (php)code>desktop-linux moby unix:///Users/theo.despoudis/.docker/run/docker.sockcode>Code language: HTML, XML (xml)
DOCKER_TLS_VERIFY
: Set this to true or 1 if you donât want to skip SSL certificate verification between your CLI tool and the dockerd daemon. This means that any certificate you use needs to be valid or the operation will fail.
DOCKER_CONFIG
: This is the location of the Docker configuration files. By default, it is set to .docker inside the userâs home directory.
Config Files
The
DOCKER_CONFIG
env variable specifies the folder that the CLI tool will use to configure it using a special config.json. If you want to use a different config.json for a particular command, you need to use the --config instead.
Using config files allows the user to provide overrides and common options for Docker commands. For example, to assign a default format output for different kinds of listing options like images, containers, or secrets, you can use:
// config.json
{
"imagesFormat": "table {{.ID}} {{.Repository}} {{.Tag}} {{.Size}}"
}
Code language: JSON / JSON with Comments (json)
This is equivalent to using the following command:
$ docker image list --format "table {{.ID}} {{.Repository}} {{.Tag}} {{.Size}}"Code language: PHP (php)
You can also specify custom HTTP headers using the HttpHeaders field and certain build time arguments for --build-arg. The available config options are
documented here
.
It is recommended that you store these files in a configuration management tool so that they can be updated automatically when you need to change certain values using a version control system.
Useful Commands
Now, weâll explore some of the most useful and practical commands to know when using the Docker CLI tool. Many of these commands accept arguments in a specific place, so you need to make sure you pass them in the correct order. You might want to review the list of available commands in the
reference docs
section.
Docker Create
The create (or container create) command creates a new container out of an existing base image without starting it. You can name the container and attach volumes, environment variables, and other configurations. For example:
$ docker container create -it --name example busybox
A883f7e9295b42ade570ac2883fbdd3654e3fe6c6d3aa41d05872f16a46835a7
This creates a container named example out of the BusyBox image with a status of CREATED. Then you can use the start command to change its status to RUNNING.
Docker Build
This builds an image out of a Dockerfile. You need to provide a path or the location of the Dockerfile, specify a URL, or use STDIN instructions to build the image. For example, given that there is a Dockerfile in the current folder, you just need to run:
$ docker build .
This will create a new image based on the instructions you provided. You also have the option to override some of the build parameters using arguments.
Docker Pull
The pull command downloads the specified image from the registry into the local Docker filesystem. Once the image is downloaded, you will be able to list it using the docker image ls command:
$ docker pull alpine:latest
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest b2aa39c304c2 10 seconds ago 7.05MB
Docker Run
The docker run command combines multiple commands for creating or pulling a container and running it with the provided options. If an image does not exist in the local host, for example, it will first pull it from the default registry, then create and run it all in the same command. The following example shows what this flow looks like:
$ docker run --name redis -p 6379:6379 -d redis:latest
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
3665d49a6c759ad832bf60665e105060935db40a390a87a9f973ff2b81d92c0b
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3665d49a6c75 redis:latest "docker-entrypoint.sâ¦" 5 seconds ago Up 4 seconds 0.0.0.0:6379->6379/tcp redisCode language: JavaScript (javascript)
There are multiple configuration options you can use with run. You can learn more about them in the
docs
.
Docker Start/Stop
Starting and stopping a running container can be performed with the docker start and docker stop commands, respectively. A container can only be started if itâs available, and a container that has been started can only be stopped using the stop command once it completes its task or when stopping the dockerd process:
$ docker start nocontainer
Error response from daemon: No such container: nocontainer
Error: failed to start containers: nocontainer
$ docker start example
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a883f7e9295b busybox "sh" 38 minutes ago Up 6 seconds example
$ docker stop exampleCode language: JavaScript (javascript)
Docker Exec
The exec command is used to execute a command in a running container. It is different from run in that it cannot be used to download images from a registry or perform other actions. For example, you cannot use exec on a container that is not present. The command is called from the default directory of the container or by the specified WORKDIR option:
$ docker exec -it redis redis-cli
Error: No such container: redis
$ docker run --name redis -p 6379:6379 -d redis:latest
$docker exec -it redis redis-cli
127.0.0.1:6379> PING
PONG
127.0.0.1:6379>Code language: PHP (php)
The exec command is useful for one-off tasks, testing connectivity, printing env variables, and for debugging purposes.
Docker Compose
Docker CLI is not the only tool that connects with the dockerd daemon. Since the dockerd process exposes an API, any compatible client can interface with it. Docker Compose, which is written in Python, is another tool that can act as a client to the Docker API.
Instead of using commands directly, youâll need to specify a YAML definition of your stack. This will need to follow certain specifications. For example, the following specification defines a
Redis
server running on port 6379 and exposes the same port on the host machine. It then uses the docker-compose CLI to spin up the described service:
version: "3.9"
services:
redis:
image: "redis:alpine"
container_name: redis
ports:
- 6379:6379
$ docker-compose up -d
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------
redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d01944c30f8 redis:alpine "docker-entrypoint.sâ¦" 34 seconds ago Up 33 seconds 0.0.0.0:6379->6379/tcp redisCode language: JavaScript (javascript)
This is equivalent to using the following Docker CLI commands:
$ docker network create --network=redis-net
$ docker run --name redis -p 6379:6379 --network=redis-net -d redis:latest
You can specify one or more services under the services field, and each one will have its own config. Docker Compose makes it easier to describe full-stack Docker applications in a single file and manage deployments using simple commands.
If you need to set up multiple networks, volumes, secrets, and other resources, Docker Compose is a scalable option. You can find the whole list of available commands for the docker-compose CLI with descriptions on
this docs page
.
Docker APIs
As we mentioned earlier, the Docker CLI interacts with Docker Engine using an API exposed in the dockerd service, and developers can create their own clients to interface with it.
This API (which is
documented here
) consists of various endpoints for managing Docker containers, secrets, and services. It uses the var/run/docker.sock for incoming HTTP and TCP requests:

Here is an example of using the socat tool to request the /version info endpoint:
echo -n "GET /info HTTP/1.0" | socat UNIX-CONNECT:/var/run/docker.sock - | grep -o '{.*}' | jq
{
"ID": "45BJ:D2Z2:7MT5:YGLC:TFJZ:2XHT:MI6M:AQUC:24BZ:47MJ:SLPA:3JNX",
"Containers": 2,
"ContainersRunning": 1,
"ContainersPaused": 0,
"ContainersStopped": 1,
"Images": 4,
"Driver": "overlay2",
"DriverStatus": [
[
"Backing Filesystem",
"extfs"
],
[
"Supports d_type",
"true"
],
[
"Native Overlay Diff",
"true"
],
[
"userxattr",
"false"
]
],
â¦Code language: PHP (php)
It sends a GET request to the /info endpoint using socat, which connects to the Docker socket. The last part of this expression extracts the JSON response and prettifies it in the command line.
In addition to the dockerd handlers, there are APIs for
Docker Hub
and
Docker Registry
that you can query as well. All of these exposed APIs deal with different management options and requests.
Conclusion
Docker is a platform for managing containers, and there are many tools and services in its ecosystem. Using the Docker CLI tool, users can issue commands to create and manage containers with ease and flexibility. This article explored the basics of the CLI tool, explained its most useful commands, and showed you how it works behind the scenes.
The goal of this article was to give you a good introduction to the Docker CLI. But when it comes to working with Docker and containers, youâll do most of your learning in real-world scenarios like trying to deploy a WordPress stack consisting of WordPress, MySQL, and NGINX.