15 Docker Hacks & Tips!
Docker is one of the amazing tools I like the most. It's by far the sparkling unicorn of containerization happening in the world of software development and the amazing tool that simplified the configuration of our projects tenfold.
In this post I'll share with you some cool docker hacks and tips. Most of you are probably familiar with many of this commands, but I hope that you find one or two little nuggets from this post;
CLI
nice docker ps output
Just pipe docker ps output to less -S so that the table rows are not wrapped:
docker ps -a | less -S
follow the logs
docker logs won't watch the logs by default unless use the -f flag:
docker logs <containerid> -f
Pretty Json from docker inspect
docker inspect spits out a lots of JSON by default. You can just use jq to extract the desired values:
# list IP addresses for all containers connected to 'bridge' network
docker network inspect bridge -f '{{json .Containers}}' | jq '.[] | {cont: .Name, ip: .IPv4Address}
Or you can use the builtin go templating in docker inspect like below:
# is the last run container still running?
docker inspect --format '{{.State.Running}}' $(docker ps -lq)
Docker Command Completion
The Docker CLI syntax is very rich and constantly growing: adding new commands and new options. It’s hard to remember every possible command and option, so having a nice command completion for a terminal is a must have.
The command completion is a kind of terminal plugin, that lets you auto-complete or auto-suggest what to type in next by hitting the tab key. Docker command completion works for commands and options. The Docker team prepared command completion for the docker, docker-machine and docker-compose commands, for both Bash and Zsh shell.
read the official Docker documentation for install instructions: docker engine, docker-compose and docker-machine.
Cleaning Up
After working with Docker for some time, you start accumulating development junk: unused volumes, networks, exited containers and unused images.
Prune: Run them all
prune
is a very useful command (also works for volume
and network
sub-commands), but it is only available for Docker 1.13. So if you’re using older Docker versions, the following commands can help you to replace the prune command.
docker system prune
Remove Dangling Volumes
dangling
volumes are volumes not in use by any container. To remove them, combine two commands: first, list volume IDs for dangling volumes and then remove them.
docker volume rm $(docker volume ls -q -f "dangling=true")
Remove Exited Containers
The same principle works here too. First, list the containers (only IDs) you want to remove (with filter) and then remove them (consider rm -f
to force remove).
docker rm $(docker ps -q -f "status=exited")
Remove Dangling Images
dangling
images are untagged images, that are the leaves of the images tree (not intermediary layers).
docker rmi $(docker images -q -f "dangling=true")
Networking
Docker has an internal pool of IPs which it uses for container IP addresses. These are invisible to the outside by default and accessible via a bridge interface.
looking up port mappings
docker run
accepts explicit port mappings as parameters or you can specify -P
to map all ports automatically. The latter has the advantage of preventing conflicts and looking up the assigned ports can be done as follows:
docker port <containerId> <portNumber>
# or
docker inspect --format '{{.NetworkSettings.Ports}}' <containerId>
container IPs
Each container has it's IP in a private subnet (which is 172.17.0.0/16
by default). The IP can change with restart but can be looked up should you need it:
docker inspect --format '{{.NetworkSettings.IPAddress}}' <containerId>
docker tries to detect conflicts and will use a different subnet if needed.
taking over the hosts network stack
docker run --net=host
allows reusing the network stack of the host. Don't do this :)
Use Another Container’s Network Stack
$ docker run --net=container:<name|id> ...
The new container will attach to the same network interfaces as the other container. The target container can be specified by id
or name
.
Attachable Overlay Network
Using Docker Engine
running in swarm mode
, you can create a multi-host overlay
network on a manager node. When you create a new swarm service, you can attach it to the previously created overlay network.
Sometimes you need to attach a new Docker container (filled with different networking tools), to an existing overlay network
, in order to inspect the network configuration or debug network issues. You can use the docker run command for this, eliminating the need to create a completely new debug service
.
Docker 1.13 brings a new option to the docker network create command: attachable
. The attachable option enables manual container attachment.
# create an attachable overlay network
docker network create --driver overlay --attachable mynet
# create net-tools container and attach it to mynet overlay network
docker run -it --rm --net=mynet net-tools sh
Start Containers Automatically
When running a process inside a Docker container, a failure may occur due to multiple reasons. In some cases, you can fix it by re-running the failed container. If you are using a Docker orchestration engine, like Swarm
or Kubernetes
, the failed service will be restarted automatically.
If not, then you might want to restart
the container based on the exit code of the container’s main process, or always restart (regardless the exit code). Docker 1.12
introduced the docker run command: restart for this use case.
Restart Always
Restart the container with a restart policy of always so that if the container exits, Docker will restart it.
docker run --restart=always my_image
Restart Container on Failure
Restart the container with a restart policy of on-failure and a maximum restart count of 10.
docker run --restart=on-failure:10 my_image
That's it folks. I hope you learned a thing or two ;)
Source: