You used the Docker CLIwhen you ran thehello-world
container to test your installation. The Docker command is what you will use to interact with the Docker daemon. Using this single executable, you can do the following, and more:
- Start and stop containers
- Pull and push images
- Run a shell in an active container
- Look at container logs
- Create Docker volumes
- Create Docker networks
- Prune old images and volumes
This chapter is not meant to include an exhaustive explanation of every Docker command; instead, we will explain some of the common commands that you will need to use to interact with the Docker daemon and containers.
You can break down Docker commands into two categories: general Docker commands and Docker management commands. The standard Docker commands allow you to manage containers, while management commands allow you to manage Docker options such as managing volumes and networking.
docker help
It is quite common to forget the syntax or options of a command, and Docker acknowledges this. If you ever find yourself in a situation where you can’t recall a command, you can always depend on thedocker help
command. It will help you by providing what the command can do and how to use it.
docker run
To run a container, use thedocker run
command with the provided image name. But, before executing adocker run
command, you should understand the options you can supply when starting a container.
In its simplest form, an example command you can use to run an NGINX web server would bedocker run bitnami/nginx:latest
. This will start a container running NGINX, and it will run in the foreground, showing logs of the application running in the container. PressingCtrl +C will stop the running container and terminate the NGINX server:
nginx 22:52:27.42nginx 22:52:27.42 Welcome to the Bitnami nginx containernginx 22:52:27.43 Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-nginxnginx 22:52:27.43 Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-nginx/issuesnginx 22:52:27.44nginx 22:52:27.44 INFO ==> ** Starting NGINX setup **nginx 22:52:27.49 INFO ==> Validating settings in NGINX_* env varsnginx 22:52:27.50 INFO ==> Initializing NGINXnginx 22:52:27.53 INFO ==> ** NGINX setup finished! **nginx 22:52:27.57 INFO ==> ** Starting NGINX **
As you saw, when you usedCtrl +C to stop the container, NGINX also stopped. In most cases, you want a container to start and continue to run without being in the foreground, allowing the system to run other tasks while the container also continues to run. To run a container as a background process, you need to add the-d
, or--detach
option to your Docker command, which will run your container in detached mode. Now, when you run a detached container, you will only see the container ID, instead of the interactive or attached screen:
[root@localhost ~]# docker run -d bitnami/nginx:latest13bdde13d0027e366a81d9a19a56c736c28feb6d8354b363ee738d2399023f80[root@localhost ~]#
By default, containers will be given a random name once they are started. In our previous detached example, if we list the running containers, we will see that the container has been given the namesilly_keldysh
, as shown in the following output:
CONTAINER ID IMAGE NAMES13bdde13d002 bitnami/nginx:l
If you do not assign a name to your container, it can quickly get confusing as you start to run multiple containers on a single host. To make management easier, you should always start your container with a name that will make it easier to manage. Docker provides another option with therun
command: the--name
option. Building on our previous example, we will name our containernginx-test
. Our newdocker run
command will be as follows:
docker run --name nginx-test -d bitnami/nginx:latest
Just like running any detached image, this will return the container ID, but not the name you provided. In order to verify that the container ran with the namenginx-test
, we can list the containers using thedocker ps
command, which we will explain next.
docker ps
Often, you will need to retrieve a list of running containers or a list of containers that have been stopped. The Docker CLI has a flag calledps
that will list all running and stopped containers, by adding the extra flag to theps
command. The output will list the containers, including their container ID, image tag,entry
command, creation date, status, ports, and container name. The following is an example of containers that are currently running:
CONTAINER ID IMAGE COMMAND CREATED13bdde13d002 bitnami/nginx:latest "/opt/bitnami/script…" Up 4 hours3302f2728133 registry:2 "/entrypoint.sh /etc…" Up 3 hours
This is helpful if the container you are looking for is currently running, but what if the container has stopped, or even worse, what if the container failed to start and then stopped? You can view the status of all containers, including previously run containers, by adding the-a
flag to thedocker ps
command. When you executedocker ps -a
, you will see the same output from a standardps
command, but you will notice that the list may include additional containers.
How can you tell which containers are running versus which ones have stopped? If you look at theSTATUS
field of the list, the running containers will show a running time; for example,Up xx hours
, orUp xx days
. However, if the container has been stopped for any reason, the status will show when it stopped; for example,Exited (0) 10 minutes ago
.
IMAGE COMMAND CREATED STATUSbitnami/nginx:latest "/opt/bitnami/script…" 10 minutes ago Up 10 minutesbitnami/nginx:latest "/opt/bitnami/script…" 12 minutes ago Exited (0) 10 minutes ago
A stopped container does not mean there was an issue with running the image. There are containers that may execute a single task and, once completed, the container may stop gracefully. One way to determine whether an exit was graceful or whether it was due to a failed startup is to look at the exited status code. There are a number of exit codes that you can use to find out why a container has exited.
Exit Code | Description |
0
| The command was executed successfully without any issues. |
1
| The command failed due to an unexpected error. |
2
| The command was unable to find the specified resource or encountered a similar issue. |
125
| The command failed due to a Docker-related error. |
126
| The command failed because the Docker binary or script could not be executed. |
127
| The command failed because the Docker binary or script could not be found. |
128+
| The command failed due to a specific Docker-related error or exception. |
Table 1.3: Docker exit codes
docker start and stop
You may need to stop a container due to limited system resources, limiting you to running a few containers simultaneously. To stop a running container and free up resources, use thedocker stop
command with the name of the container, or the container ID, you want to stop.
If you need to start that container at a future time for additional testing or development, executedocker start <name>
, which will start the container with all of the options that it was originally started with, including any networks or volumes that were assigned.
docker attach
In order to troubleshoot an issue or inspect a log file, it may be necessary to interact with a container. One way to connect to a container that is currently running is by using thedocker attach <container ID/name>
command. When you perform this action, you establish a connection with the active process of the running container. If you attach to a container that is executing a process, it is unlikely that you will see any prompt. In fact, it’s likely that you will see a blank screen for a period of time until the container starts producing output that is displayed on the screen.
You should always be cautious when attaching to a container. It’s easy to accidentally stop the running process and, in turn, stop the container. Let’s use an example of attaching to a web server running NGINX. First, we need to verify that the container is running usingdocker ps
:
CONTAINER ID IMAGE COMMAND STATUS4a77c14a236a nginx "/docker-entrypoint.…" Up 33 seconds
Using theattach
command, we executedocker attach 4a77c14a236a
.
When you attach to a process, you will only be able to interact with the running process, and the only output you will see is data being sent to standard output. In the case of the NGINX container, theattach
command has been attached to the NGINX process. To show this, we will leave the attachment andcurl
to the web server from another session. Once wecurl
to the container, we will see logs outputted to the attached console:
[root@astra-master manifests]# docker attach 4a77c14a236a172.17.0.1 - - [15/Oct/2021:23:28:31 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"172.17.0.1 - - [15/Oct/2021:23:28:33 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"172.17.0.1 - - [15/Oct/2021:23:28:34 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"172.17.0.1 - - [15/Oct/2021:23:28:35 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"172.17.0.1 - - [15/Oct/2021:23:28:36 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.61.1" "-"
We mentioned that you need to be careful once you attach to the container. Those who are new to Docker may attach to the NGINX image and assume that nothing is happening on the server or a process appears to be hung so they may decide to break out of the container using the standardCtrl +C keyboard command. This will stop the container and send them back to a Bash prompt, where they may rundocker ps
to look at the running containers:
root@localhost:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUSroot@localhost:~#
What happened to the NGINX container? We didn’t execute adocker stop
command, and the container was running until we attached to the container. Why did the container stop after we attached to it?
As we mentioned, when an attachment is made to a container, you are attached to the running process. All keyboard commands will act in the same way as if you were at a physical server that was running NGINX in a regular shell. This means that when the user usedCtrl +C to return to a prompt, they stopped the running NGINX process.
If we pressCtrl +C to exit the container, we will receive an output that shows that the process has been terminated. The following output shows an example of what happens in our NGINX example:
2023/06/27 19:38:02 [notice] 1#1: signal 2 (SIGINT) received, exiting2023/06/27 19:38:02 [notice] 31#31: exiting2023/06/27 19:38:02 [notice] 30#30: exiting2023/06/27 19:38:02 [notice] 29#29: exiting2023/06/27 19:38:02 [notice] 31#31: exit2023/06/27 19:38:02 [notice] 30#30: exit2023/06/27 19:38:02 [notice] 29#29: exit2023/06/27 19:38:02 [notice] 32#32: exiting2023/06/27 19:38:02 [notice] 32#32: exit2023/06/27 19:38:03 [notice] 1#1: signal 17 (SIGCHLD) received from 312023/06/27 19:38:03 [notice] 1#1: worker process 29 exited with code 02023/06/27 19:38:03 [notice] 1#1: worker process 31 exited with code 02023/06/27 19:38:03 [notice] 1#1: worker process 32 exited with code 02023/06/27 19:38:03 [notice] 1#1: signal 29 (SIGIO) received2023/06/27 19:38:03 [notice] 1#1: signal 17 (SIGCHLD) received from 292023/06/27 19:38:03 [notice] 1#1: signal 17 (SIGCHLD) received from 302023/06/27 19:38:03 [notice] 1#1: worker process 30 exited with code 02023/06/27 19:38:03 [notice] 1#1: exit
If a container’s running process stops, the container will also stop, and that’s why thedocker ps
command does not show a running NGINX container.
To exit an attachment, rather than useCtrl +C to return to a prompt, you should have usedCtrl +P, followed byCtrl +Q, which will exit the container without stopping the running process.
There is an alternative to theattach
command: thedocker exec
command. Theexec
command differs from theattach
command since you supply the process to execute on the container.
docker exec
A better option when it comes to interacting with a running container is theexec
command. Rather than attach to the container, you can use thedocker exec
command to execute a process in the container. You need to supply the container name and the process you want to execute in the image. Of course, the process must be included in the running image – if you do not have the Bash executable in the image, you will receive an error when trying to execute Bash in the container.
We will use an NGINX container as an example again. We will verify that NGINX is running usingdocker ps
and then, using the container ID or the name, we execute into the container. The command syntax isdocker exec <options> <container name> <command>
:
root@localhost:~# docker exec -it nginx-test bashI have no name!@a7c916e7411:/app$
The option we included is-it
, which tells theexec
to run in an interactive TTY session. Here, the process we want to execute is Bash.
Notice how the prompt name changed from the original user and hostname. The hostname islocalhost
, while the container name isa7c916e7411
. You may also have noticed that the current working directory changed from~
to/app
and that the prompt is not running as a root user, as shown by the$
prompt.
You can use this session the same way you would a standardSSH connection; you are running Bash in the container and since we are not attached to the running process in the container,Ctrl +C will not stop any process from running.
To exit an interactive session, you only need to type inexit
, followed byEnter, which will exit the container. If you then rundocker ps
, you will notice that the container is still in a running state.
Next, let’s see what we can learn about Docker log files.
docker logs
Thedocker logs
command allows you to retrieve logs from a container using the container name or container ID. You can view the logs from any container that is listed in yourps
command; it doesn’t matter if it’s currently running or stopped.
Log files are often the only way to troubleshoot why a container may not be starting up, or why a container is in an exited state. For example, if you attempt to run an image and the image starts and suddenly stops, you may find the answer by looking at the logs for that container.
To look at the logs for a container, you can use thedocker logs <container ID or name>
command.
To view the logs for a container with a container ID of7967c50b260f
, you would use the following command:
docker logs 7967c50b260f
This will output the logs from the container to your screen, which may be very long and verbose. Since many logs may contain a lot of information, you can limit the output by supplying thelogs
command with additional options. The following table lists the options available for viewing logs:
Log Options | Description |
-f
| Follow the log output (can also use--follow ). |
--tail xx
| Show the log output starting from the end of the file and retrievexx lines. |
--until xxx
| Show the log output before thexxx timestamp. xxx can be a timestamp; for example,2020-02-23T18:35:13 .
xxx can be a relative time; for example,60m .
|
--since xxx
| Show the log output after thexxx timestamp. xxx can be a timestamp; for example,2020-02-23T18:35:13 .
xxx can be a relative time; for example,60m .
|
Table 1.4: Log options
Checking log files is a process you will find yourself doing often, and since they can be very lengthy, knowing options liketail
,until
, andsince
will help you to find the information in a log quicker.
docker rm
Once you assign a name to a container, the assigned name cannot be used on a different container unless you remove it using thedocker rm
command. If you had a container running callednginx-test
that was stopped and you attempted to start another container with the namenginx-test
, the Docker daemon would return an error, stating that the name is in use:
Conflict. The container name "/nginx-test" is already in use
The originalnginx-test
container is not running, but the daemon knows that the container name was used previously and that it’s still in the list of previously run containers.
When you want to reuse a specific name, you must first remove the existing container before launching a new one with the same name. This scenario commonly occurs during container image testing. You may initially start a container but encounter issues with the application or image. In such instances, you would stop the container, resolve the problems with the image or application, and wish to redeploy it using the same name. However, since the previous container with that name still exists in the Docker history, it becomes necessary to remove it before reutilizing the name.
You can also add the--rm
option to your Docker command to automatically remove the image after it is stopped.
To remove thenginx-test
container, simply executedocker rm nginx-test
:
root@localhost ~:# docker rm nginx-testnginx-testroot@localhost ~:#
Assuming the container name is correct and it’s not running, the only output you will see is the name of the image that you have removed.
We haven’t discussed Docker volumes, but when removing a container that has a volume, or volumes, attached, it’s a good practice to add the-v
option to your remove command. Adding the-v
option to thedocker rm
command will remove any volumes that were attached to the container.
docker pull/run
When running apull
, make sure to specify the architecture.docker
pull
andrun
are used to either pull an image or run an image. If you try to run a container that doesn’t exist on the Docker host already, it will initiate apull
request to get the container and then run it.
When you attempt topull
orrun
a container, Docker will download a container that is compatible with the host’s architecture. If you want to download a different image that is based on a different architecture, you can add the--platform
tag to thebuild
command. For example, if you are on a system that is running on arm64 architecture and you want to pull an x86 image, you would addlinux/arm64
as your platform. When running a pull, make sure to specify the architecture:
root@localhost ~:# docker pull --platform=linux/amd64 ubuntu:22.0422.04: Pulling from library/ubuntu6b851dcae6ca: Pull completeDigest: sha256:6120be6a2b7ce665d0cbddc3ce6eae60fe94637c6a66985312d1f02f63cc0bcdStatus: Downloaded newer image for ubuntu:22.04WARNING: image with reference ubuntu was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64/v8docker.io/library/ubuntu:22.04
Adding--platform=linux/amd64
is what told Docker to get the right platform. You can use the same parameter fordocker run
to make sure that the right container image platform is used.
docker build
Similar topull
andrun
, Docker will attempt to build the image based on the host’s architecture:arm64
. Assuming you are building on an arm64-based image system, you can tell Docker to create an x86 image by using thebuildx
sub-command:
root@localhost ~:# docker buildx build --platform linux/amd64 --tag docker.io/mlbiam/openunison-kubernetes-operator --no-cache -f ./src/main/docker/Dockerfile .
This addition tells Docker to generate thex86
version, which will run on any x86-based hardware.