Docker#
Install#
macOS#
brew install --cask docker
Important
You must use the --cask version. Otherwise only the client is included and can't run the Docker daemon. Then open the Docker app and grant privileged access when asked. Only then will you be able to use docker
.
Linux / Raspberry Pi OS:#
If you just ran apt upgrade
on your Raspberry Pi, reboot before installing Docker.
Follow the appropriate installation method.
If you don't want to have to prefix commands with sudo
add your user to the docker
group. This is equivalent to giving that user root privileges.
cat /etc/group | grep docker # see if docker group exists
sudo usermod -aG docker $USER
Follow Post-installation steps to configure log rotation.
Use#
Architecture#
Supported Architectures
Platform specifiers
Value | Normalized | Examples |
---|---|---|
aarch64 | arm64 | Apple M1/M2, Raspberry Pi 4 |
armhf | arm | Raspberry Pi 2 |
armel | arm/v6 | |
i386 | 386 | |
x86_64 | amd64 | Intel (Default) |
x86-64 | amd64 | Intel (Default) |
Docker Desktop for Apple silicon can run (or build) an Intel image using emulation.
The --platform
option sets the platform if server is multi-platform capable.
Macbook M1/M2 is based on ARM. The Docker host is detected as linux/arm64/v8 by Docker.
On a Macbook M1/M2 running a native arm64 linux image instead of an amd64 (x86-64 Intel) image with emulation:
When installing apps on the container either install the package for the ARM platform if they provide one, or run an amd64 docker image (Docker will use emulation).
See Docker host info.
You need to use the real field names (not display names) so we'll grab the info in json to get the real field names and use jq
to display it nicely. Then we'll render them using Go templates.
docker info --format '{{json .}}' | jq .
docker info --format "{{.Plugins.Volume}}"
docker info --format "{{.OSType}} - {{.Architecture}} CPUs: {{.NCPU}}"
With the default images, Docker Desktop for Apple silicon warns us the requested image's platform (linux/amd64) is different from the detected host platform (linux/arm64/v8) and no specific platform was requested.
--platform linux/amd64
is the default and the same as --platform linux/x86_64
. It runs (or builds) an Intel image.
--platform linux/arm64
runs (or builds) an aarch64 (arm64) image. Architecture used by Appple M1/M2.
docker run -it --name container1 debian # WARNING. uname -m -> x86_64 (amd64)
docker run -it --platform linux/amd64 --name container1 debian # NO warning. uname -m -> x86_64 (amd64). On Mac it emulates Intel.
docker run -it --platform linux/arm64 --name container1 debian # NO warning. uname -m -> aarch64 (arm64). Mac native.
# On a Mac M2 you can also use this image
docker run -it --name mycontainer arm64v8/debian bash # NO warning. uname -m -> aarch64 (arm64). Mac native.
Examples#
Dockerfile instruction to keep a container running
CMD tail -f /dev/null
Running containers
# sanity check
docker version
docker --help
# "docker run" = "docker container run"
docker run --name container1 debian # created and Exited
docker run -it --name container2 debian # created and Up. Interactive tty
docker run --detach --name container3 debian # created and Exited
docker run -it --detach --name container4 debian # created and Up. Running in background
docker stop container4 # Exited
docker restart container4 # Up
docker attach container4 # Interactive tty
# To have it removed automatically when it's stopped
docker run -it --rm --name mycontainer debian # created and Up. Interactive tty.
# Run bash in a new container with interactive tty, based on debian image.
docker run -it --name mycontainer debian bash
# Get the IDs of all stopped containers. Options: all, quiet (only IDs), filter.
docker ps -aq -f status=exited
Working with images and volumes
# Show all images (including intermediate images)
docker image ls -a
# Build an image from a Dockerfile and give it a name (or name:tag).
docker build -f mydockerfile -t santisbon/myimage .
docker builder prune -a # Remove all unused build cache, not just dangling ones
docker image rm santisbon/myimage
# Volumes
docker volume create my-vol
docker volume ls
docker volume inspect my-vol
docker volume prune
docker volume rm my-vol
# Start a container from an image.
docker run \
--name mycontainer \
--hostname mycontainer \
--mount source=my-vol,target=/data \
santisbon/myimage
# Get rid of all stopped containers. Options: remove **anonymous volumes** associated with the container.
docker rm -v $(docker ps -aq -f status=exited)
# You might want to make an alias:
alias drm='docker rm -v $(docker ps -aq -f status=exited)'
# or
alias drm='sudo docker rm -v $(sudo docker ps -aq -f status=exited)'
# on macOS the volume mountpoint (/var/lib/docker/volumes/) is in the VM that Docker Desktop uses to provide the Linux environment.
# You can read it through a container given extended privileges.
# Use:
# - the "host" PID namespace,
# - an image e.g. debian,
# - the nsenter command to run a program (sh) in a different namespace
# - the target process with PID 1
# - enter following namspaces of the target process: mount, UTS, network, IPC.
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
If you want to build multi-platform docker images:
docker buildx create --name mybuilder --driver docker-container --bootstrap
docker buildx use mybuilder
docker buildx inspect
docker buildx ls
Docker Compose. Multi-container deployments in a compose.yaml file.
Using Compose in Production
docker compose -p mastodon-bot-project up --detach
# or
docker compose -p mastodon-bot-project create
docker compose -p mastodon-bot-project start
# connect to a running container
docker exec -it bot-app bash
docker compose -p mastodon-bot-project down
# or
docker compose -p mastodon-bot-project stop
Kubernetes
# Convert the Docker Compose file to k8s files
kompose --file compose.yaml convert
# Make sure the container image is available in a repository.
# You can build it with `docker build` or `docker compose create` and push it to a public repository.
docker image push user/repo
# multiple -f filenames or a folder
kubectl apply -f ./k8s
kubectl get pods
kubectl delete -f ./k8s