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.
du on the data root requires
✗ 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 allocated data.
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.
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://[email protected]: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 --host ssh://[email protected]: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://[email protected]:7770"
The output looks like this:
➟ docker context create remote --description "Remote docker server" --docker "host=ssh://[email protected]: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.
➟ 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
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
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.