../

Docker commands

Command-first reference for the Docker CLI: the exact command and flags for containers, images, builds, volumes, networks, Compose, registries and cleanup, starting with a lookup table. Same versions as Docker (Docker Engine 29.x, Compose through docker compose), which explains the concepts, Compose files, networking and security in depth; writing images is in Dockerfile.

Quick lookup

I want to…Command
run a container in the backgrounddocker run -d --name web -p 8080:80 nginx
get a throwaway shell in an imagedocker run --rm -it alpine sh
list running / all containersdocker ps / docker ps -a
open a shell in a running containerdocker exec -it web sh
read or follow logsdocker logs --tail 100 -f web
stop / remove a containerdocker stop web / docker rm -f web
see why a container exiteddocker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' web
see published portsdocker port web
copy a file outdocker cp web:/etc/nginx/nginx.conf .
watch CPU and memorydocker stats
change the restart policydocker update --restart unless-stopped web
build an imagedocker build -t app:dev .
see full build outputdocker build --progress=plain .
build without cachedocker build --no-cache -t app:dev .
list / delete imagesdocker images / docker rmi app:old
tag and pushdocker tag app:dev ghcr.io/acme/app:1.0 then docker push ghcr.io/acme/app:1.0
move an image to a host without a registrydocker save app:1.0 | ssh host docker load
list volumes / networksdocker volume ls / docker network ls
start / stop a Compose projectdocker compose up -d / docker compose down
rebuild one Compose servicedocker compose up -d --build --no-deps api
follow every Compose service's logsdocker compose logs -f
run a one-off Compose commanddocker compose run --rm api bun run migrate
print the merged Compose filedocker compose config
log in to a registrydocker login ghcr.io
run commands on a remote hostdocker --context web1 ps or DOCKER_HOST=ssh://user@host docker ps
see which daemon I'm talking todocker context ls
see what uses diskdocker system df -v
clean up unused thingsdocker system prune
watch daemon eventsdocker events
check versionsdocker version

Command anatomy

docker [global flags] <object> <command> [flags] [arguments]
docker --context prod container ls -a --filter status=exited

Commands are grouped by object (management commands): container, image, volume, network, builder / buildx, compose, context, system. The common ones also have older top-level shortcuts, and both forms do the same thing.

Management formShortcut
docker container rundocker run
docker container lsdocker ps
docker container exec / logs / rm / stopdocker exec / logs / rm / stop
docker container inspectdocker inspect (any object type)
docker image lsdocker images
docker image rmdocker rmi
docker image pull / push / tagdocker pull / push / tag
docker buildx builddocker build (always BuildKit)
docker system eventsdocker events
docker volume …, docker network …no shortcut
Global flagDoes
--context prod, -c produse a saved daemon endpoint (contexts)
-H ssh://user@hosttalk to another daemon directly
--config ~/.docker-cianother config directory (credentials, defaults)
-Ddebug output
--helpafter any command: every flag, e.g. docker run --help
  • Options go before the image name. In docker run --rm alpine ls -l, -l belongs to ls: everything after the image is the container's command.
  • Containers and images take a name, a full ID or any unique ID prefix: docker rm 3f9.
  • Most commands accept several targets: docker stop web db, docker rm $(docker ps -aq -f status=exited).
  • -f means different things: --filter on ps and images, --format on inspect, --force on rm, rmi and the prune commands. Spell it out in scripts.

docker run

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
docker run -d --name web --restart unless-stopped \
  -p 127.0.0.1:8080:80 -v ./site:/usr/share/nginx/html:ro \
  nginx
FlagEffect
-d, --detachrun in the background, print the container ID
-i, -t, -itkeep stdin open / allocate a terminal; together for shells and REPLs
--rmdelete the container (and its anonymous volumes) when it exits
--name webfixed name instead of a random one; also its DNS name on user-defined networks
-p 8080:80publish container port 80 on host port 8080, on every host address
-p 127.0.0.1:8080:80publish on loopback only
-Ppublish every EXPOSEd port on random host ports
--expose 3000document a port without publishing it
-v pgdata:/var/lib/postgresqlnamed volume
-v ./conf:/etc/app:robind mount a host path, read-only
--mount type=bind,src="$PWD"/conf,dst=/etc/app,readonlyexplicit form; fails if the host path is missing
--tmpfs /tmpin-memory filesystem
-e KEY=value / -e KEYset a variable / pass it through from your shell
--env-file .envload KEY=value lines
--network appattach to a network; also host, none, container:other
--network-alias dbextra DNS name on that network
--add-host api.local:host-gatewayadd an /etc/hosts entry; host-gateway is the host's IP
-h web1, --hostnamecontainer host name
--dns 1.1.1.1DNS server for the container
--restart unless-stoppedrestart policy: no (default), on-failure[:N], always, unless-stopped
-u 1000:1000, --userrun as UID:GID or a user name from the image
-u "$(id -u):$(id -g)"run as you, so files written to bind mounts are yours
-w /app, --workdirworking directory
--entrypoint shreplace the image's ENTRYPOINT (args after the image replace CMD)
--inittiny init (tini) as PID 1: forwards signals, reaps zombie processes
--stop-timeout 30seconds docker stop waits before SIGKILL (default 10)
--stop-signal SIGQUITsignal docker stop sends first
--platform linux/amd64image platform; emulated if it differs from the host
--pull alwaysmissing (default), always or never check the registry first
--cpus 1.5CPU limit
-m 512m, --memorymemory limit; going over it means an OOM kill (exit code 137)
--pids-limit 200maximum number of processes
--shm-size 1gsize of /dev/shm (browsers, Postgres)
--ulimit nofile=65536:65536resource limits such as open files
--gpus allexpose GPUs (NVIDIA Container Toolkit)
--read-onlyread-only root filesystem; pair with --tmpfs /tmp
--cap-drop ALL --cap-add NET_BIND_SERVICEdrop Linux capabilities, add back only what's needed
--security-opt no-new-privilegesblock privilege escalation through setuid binaries
--privilegedturns off almost all isolation; avoid
-l team=api, --labelmetadata you can filter on
--log-opt max-size=10m --log-opt max-file=3rotate this container's log file
--health-cmd 'curl -f localhost/ || exit 1'healthcheck (details)

Ports

FormBinds
-p 8080:80host port 8080 on all addresses → container port 80
-p 127.0.0.1:8080:80loopback only: reachable from this machine, not the network
-p 192.168.1.10:8080:80one host address
-p 8000-8010:8000-8010a range
-p 53:53/udpUDP (/tcp is the default)
-p 80a random free host port; find it with docker port
-p 8080:80 every host address this host LAN machine host 127.0.0.1:8080 192.168.1.10:8080 web 172.17.0.2 nginx :80 -p 127.0.0.1:8080:80 loopback only this host LAN machine host 127.0.0.1:8080 192.168.1.10:8080 web 172.17.0.2 nginx :80 not reachable -p HOST:CONTAINER host port 8080 → container port 80 on Linux this skips ufw and firewalld use for databases and admin UIs without -p, :80 stays on Docker's internal network
-p HOST:CONTAINER, with an optional host address in front. Leave the address out and every interface listens.

Mounts

WantShort -v form--mount form
Named volume-v pgdata:/var/lib/postgresql--mount type=volume,src=pgdata,dst=/var/lib/postgresql
Anonymous volume-v /data--mount type=volume,dst=/data
Bind mount-v "$PWD"/conf:/etc/app:ro--mount type=bind,src="$PWD"/conf,dst=/etc/app,readonly
tmpfs--tmpfs /tmp:size=64m--mount type=tmpfs,dst=/tmp

-v with a missing host path silently creates a root-owned directory; --mount fails instead. Mount kinds and gotchas are in Docker.

./conf a host directory -v ./conf:/etc/app:ro /etc/app (read-only) kept: your files pgdata a Docker-managed volume -v pgdata:/var/lib/postgresql /var/lib/postgresql kept until volume rm memory host memory (RAM) --tmpfs /tmp /tmp gone when it stops container writable layer: every other write; deleted by docker rm image layers: read-only, shared by every container of the image
A mount covers one path. Everything else a container writes goes to its writable layer and is lost with docker rm.

Container lifecycle

CommandDoes
docker psrunning containers
docker ps -aall, including stopped
docker ps -qIDs only, for scripts
docker ps -l / docker ps -n 5the latest created / the last 5
docker ps -swith the size of each writable layer
docker ps --no-truncfull IDs and commands
docker create --name web nginxcreate without starting
docker start web / docker start -ai webstart / start attached and interactive
docker stop webSIGTERM, then SIGKILL after 10 s; -t 30 to wait longer
docker restart webstop, then start
docker kill webSIGKILL now; -s HUP sends another signal
docker pause web / docker unpause webfreeze / thaw every process
docker rm webremove a stopped container
docker rm -f webstop and remove; -v also removes its anonymous volumes
docker rename old newrename
docker wait webblock until it exits, then print the exit code
docker update --restart unless-stopped webchange the restart policy of a live container
docker update --cpus 2 --memory 1g webchange limits live
docker container pruneremove every stopped container
docker ps --format \
  'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker ps -a --filter status=exited --filter name=api
docker ps -q --filter ancestor=postgres:18
docker ps --filter publish=5432
docker ps --filter health=unhealthy
docker ps --filter label=com.docker.compose.project=shop
docker ps --format json | jq -r '.Names'

The state diagram and exit codes (137 OOM or kill, 143 SIGTERM) are in Docker.

Inspect and debug

CommandDoes
docker inspect webfull JSON: config, state, mounts, networks, health
docker inspect -f '{{.State.Status}}' webone field (templates)
docker logs webstdout and stderr of the main process
docker logs -f webfollow
docker logs -n 100 weblast 100 lines (--tail 100)
docker logs --since 10m weba window: 10m, 2h, 2026-11-11T09:00; also --until
docker logs -t webprefix timestamps
docker logs web 2>&1 | grep -i errorlogs arrive on both streams, so merge before grep
docker exec -it web shshell in a running container (bash if the image has it)
docker exec web ls /apprun one command
docker exec -it -u root web shas root, e.g. to install a debugging tool
docker exec -e DEBUG=1 -w /app web cmdwith an extra variable and working directory
docker exec -d web cmdin the background
docker attach webconnect your terminal to the main process
docker cp web:/app/out.log .copy out; works on stopped containers too
docker cp ./fix.conf web:/etc/app/copy in
docker cp web:/app - | tar tstream a directory as a tar archive
docker top webprocesses inside; docker top web aux takes ps options
docker statslive CPU, memory, network and disk I/O for running containers
docker stats --no-stream webone snapshot
docker diff webfiles changed since start: A added, C changed, D deleted
docker port web / docker port web 80published ports / the host side of one
docker events --since 1hdaemon event stream; --filter type=container

attach vs exec

docker attach webdocker exec -it web sh
Connects tothe main process (PID 1)a new process you start
exit or Ctrl-Cusually stops the containerends only that process
Leave it runningCtrl-P Ctrl-Q, only if the container was started with -itjust exit
Use fora main process you interact with, such as a REPLshells, debugging, one-off commands

Images

CommandDoes
docker pull nginxdownload nginx:latest; --platform linux/arm64 for another platform
docker pull nginx@sha256:…one exact image by digest
docker imageslocal images
docker images -ainclude intermediate images
docker images --digestsshow digests
docker images -f dangling=trueuntagged leftovers, shown as <none>
docker images -f reference='ghcr.io/acme/*'by name pattern
docker images --format '{{.Repository}}:{{.Tag}} {{.Size}}'custom columns
docker tag app:dev ghcr.io/acme/app:1.4.2add another name to the same image (no copy)
docker push ghcr.io/acme/app:1.4.2upload; --all-tags pushes every local tag of that repository
docker rmi app:oldremove a tag; the image goes with its last tag
docker rmi -f IMAGE_IDforce, even when tagged several times
docker history app:devlayers, sizes and the instruction behind each; --no-trunc
docker image inspect app:devconfig, env, entrypoint, platform, digests
docker image pruneremove dangling images
docker image prune -aremove every image that no container uses
docker image prune -a --filter until=168hthe same, older than a week
docker buildx imagetools inspect nginxa remote image's platforms and digests, without pulling
docker buildx imagetools create -t REPO:prod REPO:1.4.2add a tag in the registry, without pulling
docker save / docker loaddocker export / docker import
Works onimages, one or more, with their tagsone container's filesystem
Keepslayers, tags, history, config (CMD, ENV, ENTRYPOINT)files only, as one flat layer; no history or config; no volumes
Outdocker save -o app.tar app:1.4.2docker export -o fs.tar web
Indocker load -i app.tar (gzip, bzip2, xz also accepted)docker import fs.tar app:flat
Use formoving images to an offline hostinspecting or flattening a filesystem

docker import --change 'CMD ["/app"]' fs.tar app:flat restores a command after a flatten.

container web: a writable layer on top of the image web's writable layer (rw) COPY src/ ./src/ RUN bun install COPY package.json ./ FROM oven/bun:1 base config: CMD, ENV, USER image app:1.4.2: read-only layers + config docker save app.tar: layers, tags, history, config docker export web fs.tar: one flat layer, files only docker history lists the layers; docker diff and ps -s show a writable layer
save keeps an image as it is; export flattens what one container sees into plain files.

Build and buildx

docker build is an alias of docker buildx build, which uses BuildKit. The context is the directory (or URL) whose files the Dockerfile can COPY; .dockerignore trims it.

FlagDoes
docker build .build ./Dockerfile with the current directory as context
-t app:devname the result; repeat for more tags
-f docker/Dockerfile.prodanother Dockerfile
--target buildstop at a named stage
--build-arg VERSION=1.4.2set an ARG
--secret id=npmrc,src=$HOME/.npmrcfile secret for RUN --mount=type=secret,id=npmrc
--secret id=gh,env=GH_TOKENsecret from an environment variable
--ssh defaultforward your SSH agent to RUN --mount=type=ssh
--no-cachererun every step
--no-cache-filter depsrerun only the named stages
--pullcheck for newer base images
--progress=plainfull output of every step (the default collapses finished steps)
--platform linux/amd64,linux/arm64target platforms
--load / --pushput the result in local images / push it to the registry
-o type=local,dest=outexport the files instead of an image
--cache-from / --cache-toexternal build cache: type=registry, type=gha, type=local
--label org.opencontainers.image.revision=…image label
--checkrun build checks (lint) without building
--call=outlinelist the build arguments and secrets the Dockerfile uses (--call=targets lists stages)
--network noneno network for RUN steps
--iidfile id.txtwrite the image ID to a file
docker build - < DockerfileDockerfile from stdin, no context
docker build https://github.com/o/r.git#main:dircontext straight from a Git repository
docker build -t app:dev . context: . what COPY can read Dockerfile package.json src/ .git/ node_modules/ .env gray: .dockerignore BuildKit runs each step FROM · COPY · RUN layer cache --build-arg --secret, --ssh --load local images --push a registry -o type=local plain files in out/ --secret and --ssh mount into one RUN step; no layer keeps them --build-arg values show in docker history: never pass secrets that way
What goes into a build, and where the result can go.
buildx commandDoes
docker buildx lsbuilders and the platforms they support
docker buildx create --name multi --driver docker-container --use --bootstrapa builder in a container: multi-platform, cache export
docker buildx use multi / docker buildx use defaultswitch builder
docker buildx inspect --bootstrapstart the current builder and show it
docker buildx rm multiremove a builder
docker buildx dubuild cache usage
docker buildx pruneclear the current builder's cache (-a for all of it)
docker buildx bakebuild several targets from a file
docker buildx build --platform linux/amd64,linux/arm64 \
  -t ghcr.io/acme/app:1.4.2 --push .

Emulation versus cross-compilation and the image store are in Docker.

Bake

Bake builds named targets from docker-bake.hcl (or the build: sections of compose.yaml), in parallel.

docker-bake.hcl
group "default" {
  targets = ["api", "worker"]
}
 
target "api" {
  context = "./api"
  tags    = ["ghcr.io/acme/api:dev"]
}
 
target "worker" {
  context = "./worker"
  tags    = ["ghcr.io/acme/worker:dev"]
}
docker buildx bake                 # the "default" group
docker buildx bake api --print     # resolved config as JSON
docker buildx bake --set '*.platform=linux/arm64'
docker buildx bake --push

Volumes and networks

CommandDoes
docker volume create pgdatacreate a named volume
docker volume lslist; -f dangling=true shows unused ones
docker volume inspect pgdatadriver, mount point, labels
docker volume rm pgdatadelete (refused while a container uses it)
docker volume prunedelete unused anonymous volumes
docker volume prune -adelete unused named volumes too
docker run --rm -v pgdata:/v alpine ls -la /vlook inside a volume
# back up a volume to ./pgdata.tgz (stop writers first)
docker run --rm -v pgdata:/v:ro -v "$PWD":/b alpine \
  tar czf /b/pgdata.tgz -C /v .
# restore into a volume
docker run --rm -v pgdata:/v -v "$PWD":/b alpine \
  tar xzf /b/pgdata.tgz -C /v
CommandDoes
docker network lslist; bridge, host and none are built in
docker network create appuser-defined bridge: containers find each other by name
docker network create --subnet 10.20.0.0/24 appchoose the subnet
docker network create --internal backendno route to the outside world
docker network inspect appsettings and attached containers
docker network connect app webattach a running container; --alias db adds a DNS name
docker network disconnect app webdetach
docker network rm appdelete
docker network prunedelete networks no container uses

Compose CLI

docker compose reads compose.yaml (plus compose.override.yaml) in the current directory and acts on the whole project, or on the services you name. File syntax is in Docker.

Start and stop

CommandDoes
docker compose up -dcreate and start everything, detached
docker compose up -d --buildrebuild images first
docker compose up -d apione service plus its depends_on
docker compose up -d --no-deps apione service, leaving its dependencies alone
docker compose up -d --force-recreatenew containers even if nothing changed
docker compose up -d --remove-orphansalso remove containers of services deleted from the file
docker compose up -d -Vfresh anonymous volumes instead of reusing old ones
docker compose up --waitreturn once services are running or healthy (CI)
docker compose up --watchstart and sync file changes (develop.watch)
docker compose up --exit-code-from testsstop everything when tests exits, return its exit code
docker compose up -d --scale worker=3run replicas
docker compose stop / startstop / start containers without removing them
docker compose restart apirestart in place; does not apply edits to compose.yaml (use up -d)
docker compose downstop and remove containers and networks
docker compose down -valso the project's named and anonymous volumes: deletes data
docker compose down --rmi localalso images built by this project

Inspect

CommandDoes
docker compose ps / ps -athis project's containers; --services, -q, --format json
docker compose logsevery service, interleaved
docker compose logs -f --tail 50 api workerfollow some services
docker compose logs --since 10m -ta time window, with timestamps
docker compose logs --no-log-prefix apiwithout the service-name prefix
docker compose top / stats / eventsprocesses / resource use / event stream
docker compose imagesimages the containers use
docker compose port api 3000host address mapped to port 3000
docker compose configthe merged, interpolated model; -q only validates
docker compose config --servicesservice names (--profiles, --images, --volumes)
docker compose lsevery Compose project on this daemon
docker compose versionCompose version

exec vs run

docker compose exec api shdocker compose run --rm api sh
Containerthe one already runninga new one built from the service definition
Service must be upyesno; starts its depends_on unless --no-deps
Portsthose up already publishednot published unless --service-ports (or -p)
TTYon by default; -T turns it off (CI, pipes)same
Extras-u root, -w /app, -e K=v, --index 2 for a replica-e K=v, -v, --entrypoint sh, --build
Use forshells, inspecting live statemigrations, tests, one-off scripts

Files, projects and profiles

Flag or variableDoes
-f compose.yaml -f compose.prod.yamlmerge files, later ones win; turns off the automatic compose.override.yaml
COMPOSE_FILE=compose.yaml:compose.prod.yamlthe same from the environment (; on Windows)
-p shop, COMPOSE_PROJECT_NAME=shopproject name (default: the directory name); prefixes containers, networks and volumes, e.g. shop-api-1
--project-directory ./deploybase directory for relative paths
--env-file .env.prodvariables for ${…} interpolation
--profile debug, COMPOSE_PROFILES=debug,toolsenable services that have profiles:
--dry-runshow what a command would do

Build and pull

CommandDoes
docker compose buildbuild every service that has build:
docker compose build --no-cache --pull apione service, from scratch, with fresh base images
docker compose pullpull images; --ignore-buildable skips services with build:
docker compose pushpush the built images
docker compose watchfile sync and rebuilds, without the app logs
docker compose cp api:/app/out.txt .copy files

Registries and login

CommandDoes
docker loginDocker Hub; uses a device code you confirm in the browser
docker login -u aliceDocker Hub with a username and password or access token
docker login ghcr.ioanother registry: the host name only
… | docker login REGISTRY -u USER --password-stdinnon-interactive (CI); keeps the secret out of history
docker logout ghcr.ioforget stored credentials
docker search postgressearch Docker Hub
# GitHub Container Registry with a token
echo "$GITHUB_TOKEN" \
  | docker login ghcr.io -u USERNAME --password-stdin
# AWS ECR (the token lasts 12 hours)
aws ecr get-login-password --region eu-west-1 \
  | docker login --username AWS --password-stdin \
    123456789012.dkr.ecr.eu-west-1.amazonaws.com
# Google Artifact Registry: registers the gcloud helper
gcloud auth configure-docker europe-docker.pkg.dev
# Azure Container Registry
az acr login --name myregistry

Credentials live in ~/.docker/config.json. Without a credential helper they are stored there base64-encoded, readable by anyone who can read the file; a helper keeps them in a keychain instead. Each value below names a program called docker-credential-NAME on your PATH.

credsStore / credHelpers valueStores or fetches credentials with
osxkeychainmacOS Keychain (the default on macOS)
wincredWindows Credential Manager
passpass, GPG-encrypted files (Linux)
secretservicethe desktop keyring: GNOME Keyring, KWallet (Linux)
desktopDocker Desktop, backed by the OS keychain
ecr-loginAWS ECR tokens on demand (amazon-ecr-credential-helper)
gcloudGoogle Artifact Registry via the gcloud CLI
~/.docker/config.json
{
  "credsStore": "osxkeychain",
  "credHelpers": {
    "<account>.dkr.ecr.<region>.amazonaws.com": "ecr-login",
    "europe-docker.pkg.dev": "gcloud"
  }
}

credsStore applies to every registry; credHelpers overrides it per registry. Docker Hub rate-limits anonymous and free-plan pulls, so log in on build machines and CI runners.

Contexts and remote daemons

A context is a saved daemon endpoint plus settings. Docker Desktop, OrbStack and Colima each register one (for example desktop-linux, orbstack, colima).

CommandDoes
docker context lslist; * marks the current one
docker context showthe current context's name
docker context create web1 --docker host=ssh://deploy@web1add a remote daemon reached over SSH
docker context use web1make it the default for every following command
docker context use defaultback to the local daemon
docker --context web1 psone command only
DOCKER_CONTEXT=web1 docker psthe same, from the environment
DOCKER_HOST=ssh://deploy@web1 docker psno context needed; overrides the current context when set
docker -H ssh://deploy@web1 psthe same as a flag
docker context inspect web1endpoint details
docker context rm web1delete
docker context export web1 / importmove a context to another machine

The SSH user must be allowed to use the Docker socket on the remote host (member of the docker group, or a rootless daemon). Add ControlMaster auto, ControlPath ~/.ssh/control-%C and ControlPersist yes to that host in ~/.ssh/config so commands reuse one connection; see SSH client config.

System and cleanup

CommandShows
docker versionclient and server versions; -f '{{.Server.Version}}' for one
docker infodaemon settings: storage driver, image store, root directory, warnings
docker system dfspace used by images, containers, volumes and build cache
docker system df -vthe same, per item
docker eventslive event stream
CommandDeletes
docker container prunestopped containers
docker image prunedangling images (untagged, <none>)
docker image prune -aevery image no container uses, tagged or not; images of stopped containers stay
docker volume pruneunused anonymous volumes; named volumes stay
docker volume prune -aevery unused volume, named ones included
docker network prunenetworks no container uses
docker builder prunedangling build cache
docker builder prune -aall unused build cache
docker system prunestopped containers, unused networks, dangling images, unused build cache
docker system prune -athe above plus every image no container uses
docker system prune -a --volumesthe above plus unused anonymous volumes

Every prune asks first unless given --force, and takes --filter until=24h or --filter label=… (volume prune: label only). Named volumes go only with docker volume prune -a, docker volume rm or docker compose down -v.

Format and filter

Go templates

--format takes a Go template: fields are written {{.Field}}, table adds column headers and \t separates columns, and json prints a value as JSON. On list commands, --format json prints one JSON object per line, ready for jq. Template functions include json, join, split, lower, upper, title, pad, truncate and println, plus Go's range, index and if.

WantCommand
A custom tabledocker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
JSON linesdocker ps --format json
Image names and sizesdocker images --format '{{.Repository}}:{{.Tag}}\t{{.Size}}'
Every field you can usedocker ps --format '{{json .}}', or the full docker inspect web
Statusdocker inspect -f '{{.State.Status}}' web
Exit code, OOM killdocker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' web
Health (only with a healthcheck)docker inspect -f '{{.State.Health.Status}}' web
Main PID on the hostdocker inspect -f '{{.State.Pid}}' web
Started at, restart countdocker inspect -f '{{.State.StartedAt}} {{.RestartCount}}' web
IP addressesdocker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' web
Host port for container port 80docker inspect -f '{{(index (index .NetworkSettings.Ports "80/tcp") 0).HostPort}}' web
Environmentdocker inspect -f '{{json .Config.Env}}' web | jq
Mountsdocker inspect -f '{{json .Mounts}}' web | jq
Restart policydocker inspect -f '{{.HostConfig.RestartPolicy.Name}}' web
Compose service namedocker inspect -f '{{index .Config.Labels "com.docker.compose.service"}}' web
Log file on the hostdocker inspect -f '{{.LogPath}}' web
Image platformdocker image inspect -f '{{.Os}}/{{.Architecture}}' nginx
Image entrypoint and commanddocker image inspect -f '{{json .Config.Entrypoint}} {{json .Config.Cmd}}' nginx
Image digestdocker image inspect -f '{{index .RepoDigests 0}}' nginx

Filters

--filter key=value narrows list and prune commands. Repeating the same key means or; different keys mean and. label!=key negates.

CommandFilter keys
docker psname (substring), id, label, status, exited, ancestor, before, since, volume, network, publish, expose, health, is-task
docker imagesreference (glob), dangling, label, before, since
docker volume lsname, dangling, driver, label
docker network lsname, id, driver, label, scope, type (custom, builtin)
docker eventstype, event, container, image, label, network, volume, daemon and more
prune commandsuntil (24h, a date or a timestamp), label
KeyValues
statuscreated, restarting, running, removing, paused, exited, dead
healthstarting, healthy, unhealthy, none
type (events)container, image, volume, network, daemon, plugin and Swarm objects
event (containers)create, start, die, stop, kill, oom, health_status, exec_start and more
docker ps -a --filter status=exited --filter status=dead
docker ps --filter name=api --filter status=running
docker images --filter reference='ghcr.io/acme/*'
docker events --filter type=container --filter event=die
docker image prune -a --force --filter until=72h
docker rm $(docker ps -aq --filter status=exited)

References