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¶
Dockerfile nomenclature¶
Docker nomenclature is sometimes unintuitive.
ARG defines an argument that passed when building, not when executing. https://docs.docker.com/reference/dockerfile#arg
ENTRYPOINT is a command and its optional arguments that should always run by default inside the container. You can think of the as the default command. https://docs.docker.com/reference/dockerfile#entrypoint
CMD is arguments for the ENTRYPOINT if it exists, otherwise it is the command that should run in the container. https://docs.docker.com/reference/dockerfile#cmd
For example:
With this built container, if you run docker run -ti -c "echo hi" this would run /usr/bin/bash -c "echo hi". But you can also override the entrypoint with --entrypoint=/usr/bin/python so these mechanics do overlap a bit and don't always make intuitive sense.
Show help on the run command¶
Show the history of an image, and count its layers¶
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.
Run a docker image in an interactive shell¶
-i,--interactive-t,--tty
https://docs.docker.com/engine/reference/commandline/run
Get a bash terminal on a running docker container¶
Determine if you are running inside docker¶
Exit code will be 0 in docker:
Run a docker image and assign it a hostname, and a docker name¶
The hostname shows up to the OS. The docker name can be used to interact with the container:
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.
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.
Run a container with a shared directory¶
We are specifying :ro to make this a read-only mount. Default is rw.
Show configuration parameters for a container¶
This shows more things that you can configure, like DNS, DNS search, etc..
Show what has changed since a container was started¶
https://docs.docker.com/engine/reference/commandline/diff
View the terminal scrollback of a a container¶
List all containers, including ones that have been stopped¶
This allows you to restart previous instances of a container.
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.
Stop a named container¶
Update the restart policy on a running container¶
Delete all unused stuff¶
This will be interactive.
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.
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:
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"
Convert a docker-compose.yml file into other formats¶
By default, the destination format is a kustomize dir:
You can also convert into a helm chart:
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/oras-project/oras: CLI tool to work with arbitrary artifacts stored in OCI registries
- https://danielquinn.org/blog/developing-with-docker
- http://chainguard.dev: security hardened base images for some popular software.
- https://www.rapidfort.com: security hardened images, runtime scan tools to locate running code that is vulnerable, and a tool that removes unused components from images.
- https://ubuntu.com/containers/chiseled: tools to remove unused components from docker images for reduced size and improved security.
- https://github.com/containers/skopeo: "Work with remote images registries - retrieving information, images, signing content"
- https://github.com/regclient/regclient: "Docker and OCI Registry Client in Go and tooling using those libraries."
- https://github.com/google/go-containerregistry/tree/main/cmd/crane: "crane is a tool for interacting with remote images and registries."