docker
"An open source project to pack, ship and run any application as a lightweight container." - https://www.docker.com
Naming inconsistencies
As of 2024, there are a bunch of frustrating naming inconsistencies with Docker and OCI images. The docker image tag documentation shows the "image name" as being broken down into the following components: [registry[:port]/][namespace/]repository[:tag]
. Unfortunately this does not harmonize with what is used in various tools, including the official Docker tools.
For example, the docker
command line shows the full "image name" minus the "tag" component if you ask it for the "repository":
$ docker images quay.io:443/prometheus/busybox:glibc --format=json | jq -r .Repository
quay.io:443/prometheus/busybox
And the docker python module shows the entire "image name" when you ask it for the "tag"
>>> client.images.get('quay.io:443/prometheus/busybox:glibc').tags
['quay.io/prometheus/busybox:glibc']
Other documents list other definitions. I think that the community needs to get this terminology straight in order for us to build consistent, resilient software. There are some discussions open about this topic, but it does not seem to be high priority:
- https://github.com/opencontainers/artifacts/issues/32#issuecomment-954898503
- https://github.com/opencontainers/distribution-spec/issues/279
Docker Desktop
In August 2021, Docker pulled a license bait and switch with Docker Desktop. If you want a Docker Desktop alternative on macOS that has a docker
command but doesn't use Docker Desktop, you can do the following:
brew install hyperkit minikube docker kubernetes-cli
minikube config set driver hyperkit
minikube start
eval $(minikube docker-env)
This will give you docker
commands that targets the minikube CRI, and is actually a great dev environment.
Alternatively, if you have a linux machine that runs docker handy, you can skip the minikube stuff and export DOCKER_HOST=ssh://linux-docker-host
to launch containers on the linux dockerd. This has the caveats that you cannot mount local filesystems into the remote docker host, and if you want to use it for building your project directory will be sent over the network to the remote docker host.
Examples
Show help on the run command
docker help run
Show the history of an image, and count its layers
docker history ubuntu:bionic | nl -ba -v0
Run the docker command against a remote host
Using this method can save your mac a lot of resources and easily get a laptop to have access to a much larger machine's resources. Not all features work, such as bind mounts from the local machine.
DOCKER_HOST=ssh://some-linux-machine docker ps
Run a docker image in an interactive shell
docker run -i -t ubuntu:focal bash
- -i, --interactive
- -t, --tty
https://docs.docker.com/engine/reference/commandline/run
Get a bash terminal on a running docker container
docker exec -i -t running-container-name bash
Determine if you are running inside docker
Exit code will be 0 in docker:
grep -q docker /proc/1/cgroup
Run a docker image and assign it a hostname, and a docker name
docker run --hostname=somehost1 --name="host1" -ti centos:centos6 bash
The hostname shows up to the OS. The docker name can be used to interact with the container:
docker ps host1
Show a complete vertically oriented list of docker processes
docker ps
has no --json
flag, but you can work around that with golang style formatting.
docker ps --no-trunc --format='{{ . | json }}' | jq -S .
This trick also works with docker images
, which also lacks a --json
arg.
Show a table of docker containers sorted by space used in the container (not by the image)
$ docker ps --format="{{.Size}}\t{{.ID}}\t{{.Image}}\t{{.Names}}" |
sort -h -k1 |
column -t
0B (virtual 101MB) 2f7ba92f1e66 wan-connection-logger wan-connection-logger
0B (virtual 413MB) 21d474032755 gitlab/gitlab-runner gitlab-runner
2B (virtual 392MB) c15b2ad88901 mariadb:10.4-bionic mariadb
312kB (virtual 710MB) ccee541f32c2 jacobalberty/unifi unifi
1.45MB (virtual 2.3GB) a9a60f4c6efc homeassistant/home-assistant home-assistant
239MB (virtual 412MB) 5d9f9cc3b46a plexinc/pms-docker:plexpass plex
Run a container with a tcp port map
This maps port 18022 of the host to 22 of the guest.
docker run -ti -p 18022:22 centos:7 bash
Run a container with a shared directory
We are specifying :ro to make this a read-only mount. Default is rw.
docker run -d -v "$HOME/www/:/var/www/html/:ro" php:5.4.35-apache
Show configuration parameters for a container
This shows more things that you can configure, like DNS, DNS search, etc..
docker inspect host1
Show what has changed since a container was started
docker diff "$some_running_image"
https://docs.docker.com/engine/reference/commandline/diff
View the terminal scrollback of a a container
docker logs "$some_running_image"
List all containers, including ones that have been stopped
This allows you to restart previous instances of a container.
docker ps -a
https://docs.docker.com/engine/reference/commandline/ps
Start a named container
By default containers don't restart when your system restarts, so you have to start them manually.
docker start ttrss
Stop a named container
docker stop ttrss
Update the restart policy on a running container
docker update --restart=unless-stopped "$some_running_image"
Delete all unused stuff
This will be interactive.
docker system prune
Delete old containers
https://docs.docker.com/engine/reference/commandline/rm
You may have to remove -r
from xargs
on non-GNU systems.
docker ps -a --format="{{.ID}} {{.Status}}" |
awk '$2 == "Exited" && $5 ~ /(days|weeks|months)/ {print $1}' |
xargs -r docker rm
A more systematic approach is to use Docker Custodian.
Delete old images
This is safe to run as long as valuable containers are running, as it won't delete any images that are attached to running containers.
docker rmi $(docker images | grep '^<none>' | awk '{print $3}')
https://docs.docker.com/engine/reference/commandline/rmi
A more systematic approach is to use Docker Custodian.
Show processes running inside all docker containers
On hosts without cgroup integration, run:
pgrep docker | xargs -n1 pstree
Show a list of tags for a given image on docker hub
$ curl --silent -f -lSL "https://index.docker.io/v1/repositories/org-name/image-name/tags" |
jq '.[].name'
"latest"
"0.11.1"
"1.3.0"
"1.5.0"
"2.0.0"
Quay has a swagger console to discover more API uses
$ curl --silent -f -lSL "https://quay.io/api/v1/repository/org-name/image-name/tag" |
jq '.tags[].name'
"2.0.0"
"latest"
"1.3.0"
See Also
- https://www.docker.io: Main page
- http://dockerfile.github.io: Trusted builds of FOSS software
- https://registry.hub.docker.com: Public docker images
- https://docs.docker.com/build/builders: How to build Dockerfiles
- https://cloud.google.com/solutions/best-practices-for-building-containers
- https://github.com/wagoodman/dive: A tool for exploring each layer in a docker image
- https://hpcw.github.io: High Performance Container Workshop videos
- https://github.com/regclient/regclient: Perform operations on OCI registries
- https://github.com/oras-project/oras: CLI tool to work with arbitrary artifacts stored in OCI registries
- https://github.com/containers/skopeo: "Work with remote images registries - retrieving information, images, signing content"
- https://danielquinn.org/blog/developing-with-docker