free-tech

Docker CLI Commands


Introduction


We 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.

Terminology


Throughout this article you’ll hear about

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.

Setup


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:
docker version
Client:
Cloud integration: v1.0.24
Version:           20.10.17
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
Docker CLI Commands

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 images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
postgres     latest    1133a9cdc367   2 weeks ago   376MB
docker images -q
1133a9cdc367

We can then create a container from an image, without specifying a name for the container:
docker create postgres
3fa3bc56a56f7a0bf4bb9a34ad94941f2066643cc476d3a3e2c3223784333ee0
Docker CLI Commands

This command shows details of the running containers (which we have none at the moment):
docker ps
CONTAINER 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 -a
CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS    PORTS     NAMES
3fa3bc56a56f   postgres   "docker-entrypoint.s…"   About a minute ago   Created             strange_easley
docker ps -aq
3fa3bc56a56f
Docker CLI Commands

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 images
REPOSITORY   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
2e5afd84fd493a35a00d6e83a848415e0eac52382e1f088af6725198ab09e3cb

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 -a
CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS    PORTS     NAMES
2e5afd84fd49   mysql      "docker-entrypoint.s…"   About a minute ago   Created             mysql-container
3fa3bc56a56f   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=my
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS    PORTS     NAMES
2e5afd84fd49   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=running
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Running Containers


The start command will start any stopped container.

Let’s start the “mysql_container” and check for running containers:
docker start mysql-container
mysql-container
docker ps
CONTAINER 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_container
2022-07-27 16:32:47+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of the following:
- MYSQL_ROOT_PASSWORD
- MYSQL_ALLOW_EMPTY_PASSWORD
- MYSQL_RANDOM_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 mysql
23aa7eb5bb5d0e6266f649c5d3cb9f92bcb09bcd5dcd8f8d3c9aa4286ab664dd

Now we can see the one mysql container is running called “some-mysql”:
docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                 NAMES
23aa7eb5bb5d   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-mysql
some-mysql
docker ps
CONTAINER 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-mysql
some-mysql
docker ps
CONTAINER 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-mysql
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
999                 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-mysql
some-mysql
docker stop some-mysql
some-mysql
docker ps
CONTAINER 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).

Removing Containers


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 prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
2e5afd84fd493a35a00d6e83a848415e0eac52382e1f088af6725198ab09e3cb
3fa3bc56a56f7a0bf4bb9a34ad94941f2066643cc476d3a3e2c3223784333ee0

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 -a
CONTAINER 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)
23aa7eb5bb5d

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-mysql
Error response from daemon: You cannot remove a running container 23aa7eb5bb5d0e6266f649c5d3cb9f92bcb09bcd5dcd8f8d3c9aa4286ab664dd. Stop the container before attempting removal or force remove

In this case either:

Removing Images


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

Author: George Marklow.