3 Rather Unknown Docker Commands That Will Help You in a Variety of Scenarios
If you're using Docker for a while you probably already have a simple and effective workflow tailored to you, which includes some of your favorite docker commands (subcommands to be technically correct).
For example, I used to remove the containers that are not running using a long command which looks like this docker container rm $(docker container ps -qf status=exited)
, it worked, obviously throwing an error whenever there were no dangling containers. This stopped one day when I found out that we also have a prune
subcommand for containers! So now that long command has come down to a simple docker container prune
.
The point is even though many of us have been using Docker for a while, there is the chance that some things might've gotten overlooked, or maybe even forgotten through time.
In this article, I'm going to give you three docker subcommands, that might be new to you, or you're not using them much but I think you should.
These sub-commands might also include their own sub-commands.
1. The system sub-command
Docker has a system
command that gives you some system-level information related to docker. You have actually been using one of its subcommands for a while now. Remember docker info
? This command is actually docker system info
.
To know more about this subcommand and what it offers, run the --help
option on it.
➟ docker system --help
Usage: docker system COMMAND
Manage Docker
Commands:
df Show docker disk usage
events Get real time events from the server
info Display system-wide information
prune Remove unused data
Run 'docker system COMMAND --help' for more information on a command.
Let's go through each of these subcommands since I think they're all very critical.
Docker system df
Have you ever been in a situation where your server's disk space seemed to be nearly full? To inspect whether it's the containers (running/volumes) you probably have been using the du
command directly on the data root.
Using du
on the data root requires sudo
access.
✗ du -h --max-depth=1 /var/lib/docker
du: cannot read directory '/var/lib/docker': Permission denied
4.0K /var/lib/docker
Not only that, to explicitly know how much the volumes are allocating or the images, you'd have to run the command several times.
➟ sudo du -h --max-depth=0 /var/lib/docker/volumes && \
sudo du -h --max-depth=0 /var/lib/docker/image && \
sudo du -h --max-depth=0 /var/lib/docker/
A much better alternative is to call the docker system df
command. This will automatically detect the data root and accordingly print all the information regards to the disk usage by Docker containers, images and volumes.
Here's what my current system shows (it's a new install)
➟ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 10 1 84.17MB 84.17MB (100%)
Containers 1 1 8.219MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
Docker system prune
If you ever wanted to remove (1) all unused networks, (2) dangling images, (3) stopped containers, (4) all unused volumes, there's a big chance you used, or are used to using four separate commands to achieve the job.
docker network prune && \
docker image prune && \
docker volume prune && \
docker container prune
If you didn't previously know about container prune
like me then the command gets even bigger. Well lucky for us, all of this can be done using just a simple command, namely docker system prune --volumes
.
By default docker system prune
doesn't remove the volumes, for that you need to use the --volumes
option. This command additionally also clears the build cache for you.
You can use the -f
option to avoid the (sometimes) annoying prompt. See the example below:
➟ docker system prune --volumes -f
Deleted Containers:
672d39c1a78969887f411ce9139e74e5b21c31fccf2bcf8c1190a9e166089ede
Deleted Networks:
Example
SSHnet
Dummy
Deleted Volumes:
dummy
Total reclaimed space: 0B
Other options include -a
that removes all unused images, not just the dangling ones.
Docker system events
This command may not be useful all the time, but it's something I think everyone should be aware of.
docker system events
or docker events
for short gives you real-time events directly for the docker daemon (dockerd
). This can help monitor certain events like when an image has been removed, for instance.
See the screenshot below to understand this better.
2. The context subcommand
This is another beautiful subcommand that not many are aware of as far as I know. A context to any docker command execution is a couple of key-value pairs, that includes but are not limited to the endpoint, host, maybe some config file, etc.
Once you have a context created, it can be reused later on.
One of the biggest practical use cases, especially for me has been creating separate contexts for the individual servers that I have docker running. Since most of my work revolves around it, instead of logging into the server every single time, I use my local client with the remove docker server over SSH.
Let me show you how I achieve this with docker contexts.
First I have a server deployed on Linode, that has docker running. If I were to access the remote docker daemon, without contexts, I'd be using a command like the following
➟ docker --host ssh://debdut@194.195.116.210:7770 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb4fa8390ab7 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 2 hours ago Up 2 hours reverse-proxy_letsencrypt_1
ccdda507facb jwilder/nginx-proxy "/app/docker-entrypo…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp reverse-proxy_reverse_proxy_1
So to access the remote daemon either I'd have to alias docker
to docker --host ssh://debdut@194.195.116.210:7770
, or use an environment variable DOCKER_HOST
. But these make switching to other hosts very difficult. An easier alternative is to just create a context.
The following command creates a context named remote
, for a docker endpoint with a different host than the local.
docker context create remote --description "Remote docker server" --docker "host=ssh://debdut@194.195.116.210:7770"
The output looks like this:
➟ docker context create remote --description "Remote docker server" --docker "host=ssh://debdut@194.195.116.210:7770"
remote
Successfully created context "remote"
Now you can either use the -c
option with docker
if you want to check something quickly or for repeated operations, change the context to this new one.
With the -c
option:
➟ docker -c remote ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb4fa8390ab7 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 2 hours ago Up 2 hours reverse-proxy_letsencrypt_1
ccdda507facb jwilder/nginx-proxy "/app/docker-entrypo…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp reverse-proxy_reverse_proxy_1
With docker context use [CONTEXT_NAME]
:
➟ docker context use remote
remote
Current context is now "remote"
~
➟ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb4fa8390ab7 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 2 hours ago Up 2 hours reverse-proxy_letsencrypt_1
ccdda507facb jwilder/nginx-proxy "/app/docker-entrypo…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp reverse-proxy_reverse_proxy_1
To get out of the context, use the use
subcommand with default
for the context name:
➟ docker context use default
default
Current context is now "default"
~
➟ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. The pause & unpause subcommand
Big deployment (applications) are now divided into multiple components, better known as micro-services. When you deploy them using something like docker-compose, sometimes what happens is that one component starts up before the one[s] it depends on. This is a problem because since its dependency (or dependencies) hasn't started yet, this component is going to fail to start.
You can mitigate this problem by using restart policies in Docker, but they don't prevent flooding the log with failed attempts. What I used to do at the beginning is just stop the container/service until the dependency has completely started up.
A better way is to just pause the container for a while, and once the necessary service[s] has successfully come up, you can unpause the container and everything will move forward from there just fine.
Although containers are fast to spin up, this is an even faster way to counter such an issue.
The syntax for pause
and unpause
is quite simple.
docker pause [CONTAINER_NAME|ID]
docker unpause [CONTAINER_NAME|ID]
That concludes this article for now. If I find any more such commands, useful or interesting, I'll update this article accordingly.
Do you have a Docker command that you think should've been on this list? Do let me know in the comments down below.