A Tour of Docker CLI Commands — Part I
Get Up and Running with the Essentials
I put together this quick, introductory tutorial workflow to help you to familiarize yourself with the Docker CLI.
It doesn’t cover everything. There are several out-of-scope topics which will be covered in a follow-up Part II tutorial.
Throughout this article you’ll hear about
- Docker Hub
Docker Hub is a container image directory where images are stored and available to be pulled for developers to build containers for services or web apps.
It is a public registry maintained by Docker, an open-source project with PaaS services that distribute software using OS-level virtualization
A Docker image has the deployment and execution configuration, and dependencies needed by a container runtime. It is a static representation of the app or service and its configuration and dependencies.
A developer builds an application or service using Docker and bundles it together with any dependencies into a container, which is an instance of a Docker image and can be run anywhere (on-premises, in the cloud etc).
The developer runs a Docker host the development computer (Windows, Linux, macOS), which is the machine that Docker Engine is installed and where Docker images are deployed.
Check here to get started for free with Docker.
Once you’ve completed all the installation steps, run the following command on your Terminal to check that Docker was installed successfully:
Cloud integration: v1.0.24
API version: 1.41[...]
Pulling Images and Creating Containers
Let’s pull the Docker image Postgres.
Use the following command to pull the Postgres image from the Docker Hub registry:
docker pull postgres
We can confirm we’ve got the Docker image using the following command, and using the — q flag to display the image id only:
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest 1133a9cdc367 2 weeks ago 376MBdocker images -q1133a9cdc367
We can then create a container from an image, without specifying a name for the container:
docker create postgres3fa3bc56a56f7a0bf4bb9a34ad94941f2066643cc476d3a3e2c3223784333ee0
This command shows details of the running containers (which we have none at the moment):
docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
We can run the following commands to show all containers irrespective of whether they are running or not, as well as the those image Ids only.
This time, we can see the one container created from the Postgres image.
docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3fa3bc56a56f postgres "docker-entrypoint.s…" About a minute ago Created strange_easleydocker ps -aq3fa3bc56a56f
Let’s pull a second image from Docker Hub, this time MySQL:
docker pull mysql
Check to see we’ve now got two images now:
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 38643ad93215 17 hours ago 446MB
postgres latest 1133a9cdc367 2 weeks ago 376MB
Let’s create a container for the MySQL image, this time specifying a container name “mysql-container”:
docker create --name mysql-container mysql
The create command creates a new container from a docker image, but again the container doesn’t run immediately (same as the container we created from the Postgres image).
Now check we’ve got two containers (irrespective of status):
docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES2e5afd84fd49 mysql "docker-entrypoint.s…" About a minute ago Created mysql-container3fa3bc56a56f postgres "docker-entrypoint.s…" 15 minutes ago Created strange_easley
Searching for Containers
Let’s do that again, but this time filtering the results to show only containers named “my” (again, irrespective of status):
docker ps -a -f name=myCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES2e5afd84fd49 mysql "docker-entrypoint.s…" 4 minutes ago Created mysql-container
We can also show we don’t have any running containers by filtering on status “running”:
docker ps -a -f status=runningCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
The start command will start any stopped container.
Let’s start the “mysql_container” and check for running containers:
docker start mysql-containermysql-containerdocker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Wait a minute!? Shouldn’t there be a running container?
Let’s check the logs on that container as follows:
docker container logs mysql_container2022-07-27 16:32:47+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specifiedYou need to specify one of the following:- MYSQL_ROOT_PASSWORD
As expected, in order to start a MySQL server instance we’ve got to supply some arguments.
The MySQL page on Docker supplies the following template command, which I’ve just run without making any changes:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql23aa7eb5bb5d0e6266f649c5d3cb9f92bcb09bcd5dcd8f8d3c9aa4286ab664dd
Now we can see the one mysql container is running called “some-mysql”:
docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES23aa7eb5bb5d mysql "docker-entrypoint.s…" 28 seconds ago Up 27 seconds 3306/tcp, 33060/tcp some-mysql
What happened was the run command both created and started a totally new container called “some-mysql”.
Contrast that with the create command we used to create the “mysql-container”, which only creates a new container but doesn’t start it.
The part of the run command that specifies the name to use is as follows:
docker run --name some-mysql [...]
Pausing, Unpausing, Restarting and Stopping Containers
We can pause and unpause the running container “some-mysql” as shown below.
Notice that we’re using the ps command again after the pause command, which tells us whether the container is paused:
docker pause some-mysqlsome-mysqldocker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES23aa7eb5bb5d mysql "docker-entrypoint.s…" 17 minutes ago Up 21 seconds (Paused) 3306/tcp, 33060/tcp some-mysql
Let’s now unpause it and check again:
docker unpause some-mysqlsome-mysqldocker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23aa7eb5bb5d mysql "docker-entrypoint.s…" 18 minutes ago Up About a minute 3306/tcp, 33060/tcp some-mysql
We can list the processes running inside the container to see a particular PID using the top command:
docker container top some-mysqlUID PID PPID C STIME TTY TIME CMD999 3503 3478 2 16:55 ? 00:00:07 mysqld
We can restart this running container as shown below.
We can also stop it, then confirm that no containers are running anymore:
docker restart some-mysqlsome-mysqldocker stop some-mysqlsome-mysqldocker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
We can also filter the container logs for the text “SHUTDOWN” using grep command-line utility for searching plain-text (a further explaination of 2>&1 can be found here).
docker logs some-mysql 2>&1 | grep "SHUTDOWN"2022-07-27T16:38:44.799824Z 10 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.30).2022-07-27T16:43:34.052929Z 0 [System] [MY-013172] [Server] Received SHUTDOWN from user <via user signal>. Shutting down mysqld (Version: 8.0.30).
We can remove all containers that are stopped using the prune command as shown below.
We have one container running and two others that aren’t, so we’d expect to see two deleted containers:
docker container pruneWARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] yDeleted Containers:
To verify that we’ve only got one container left (the one still running) let’s run the command to list all containers (regardless of status):
docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23aa7eb5bb5d mysql "docker-entrypoint.s…" 25 minutes ago Up 8 minutes 3306/tcp, 33060/tcp some-mysql
We can remove all containers regardless of status with the force flag.
Since we’ve only got one container left (currently running), we expect a single container to be removed:
docker rm -f $(docker ps -a -q)
We could also have deleted that container by name as shown below.
If you don’t stop the container, the CLI will complain that it’s trying to delete a running container:
docker rm some-mysqlError response from daemon: You cannot remove a running container 23aa7eb5bb5d0e6266f649c5d3cb9f92bcb09bcd5dcd8f8d3c9aa4286ab664dd. Stop the container before attempting removal or force remove
In this case either:
- stop the container then remove it, or
- remove it using the force flag.
Finally, let’s remove the Postgres and MySQL images using the rmi command:
docker rmi mysql
docker rmi postgres
It makes sense that this operation won’t work on an image if it’s being used by containers (try this yourself).
In order to force-remove an image you would use the force flag:
docker rmi -f mysql
Thanks for reading! Let me know what you think in the comments section below, and don’t forget to subscribe. 👍