Docker commands are long relative to how often you type them, which makes them worth aliasing. Add them faster than you use them, though, and you end up with a pile of abbreviations you can't remember. These are the ones that are still in my rc file after a few years, and the ones I took back out.

Just shorter
alias d='docker' alias dc='docker compose'
Those two alone change how the day feels. One caveat on the second.
dc is already a command. It's the reverse-Polish desk calculator that ships with bc, present by default on macOS and most Linux distributions. Shadowing it rarely causes trouble, but you will be briefly confused the day you type dc on someone else's machine and get a calculator. Use dco if that bothers you.
Also worth noting: docker-compose with a hyphen is the v1 name and is out of support. Anything written today should use docker compose with a space.
Making docker ps readable
Default docker ps spends the terminal width on CONTAINER ID, IMAGE and COMMAND, then wraps the names and ports you actually wanted. Cut the columns down:
alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
Before you alias it, there's another option. Put it in ~/.docker/config.json and plain docker ps changes its default output:
{ "psFormat": "table {{.Names}}\t{{.Status}}\t{{.Ports}}", "imagesFormat": "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" }
Unlike an alias, that applies no matter which shell you're in. The flip side is that any script on the same machine parsing docker ps output now sees something different. Config file on a personal machine, alias on a shared server, is where I've landed.
Getting a shell in a container
This takes an argument, so it's a function rather than an alias.
dsh() { docker exec -it "$1" sh -c 'command -v bash >/dev/null 2>&1 && exec bash || exec sh' }
For a while mine was just docker exec -it xxx bash, which failed every single time against an Alpine-based image, because there is no bash in there. Falling back to sh when bash is missing stopped that from being a daily interruption.
More often than not the real problem is remembering the container name, so if you have fzf, let it pick:
dsh() { local c c=$(docker ps --format '{{.Names}}' | fzf --select-1 --exit-0) || return docker exec -it "$c" sh -c 'command -v bash >/dev/null 2>&1 && exec bash || exec sh' }
--select-1 skips the menu when there's only one candidate, and --exit-0 bails out when there are none — without it you get an empty picker whenever nothing is running.
Logs
alias dlog='docker logs -f --tail 100'
Without --tail, Docker replays everything since the container started before it begins following. On something that's been up for a week, you wait. Defaulting to the recent lines is almost always what you meant.
Stopping everything
alias dstop='docker stop $(docker ps -q)'
This errors when nothing is running: docker ps -q returns nothing, and docker stop gets called with no arguments.
"docker stop" requires at least 1 argument.
Harmless, but the red text every time gets old, so mine is a function that stays quiet:
dstop() { local ids ids=$(docker ps -q) [ -z "$ids" ] && return 0 docker stop $ids }
The cleanup ones
This is the section to read before aliasing anything.
alias dprune='docker system prune -f'
docker system prune removes stopped containers, networks no container is using, dangling (untagged) images, and build cache. -f skips the confirmation. Everything in that set can be recreated.
The trouble is the two flags usually shown alongside it:
-aalso removes unused images including tagged ones, so your next several builds and pulls are slow.--volumesalso removes unused volumes. If a named volume holds your database and the container happens to be down, running this deletes it.
Don't put docker system prune -af --volumes behind something short like dclean. A typo or a stray history recall will eventually destroy something you can't get back. When you genuinely need the disk space, type the whole thing deliberately.
If it's images you want to tidy, this one has a much clearer blast radius:
alias dprunei='docker image prune -f'
Compose
alias dcu='docker compose up -d' alias dcd='docker compose down' alias dcl='docker compose logs -f --tail 100' alias dcr='docker compose run --rm'
The --rm in dcr matters. docker compose run creates a fresh container each time and leaves it behind when it exits, so without --rm stopped containers quietly accumulate.
docker compose down takes -v to delete volumes too. Don't make that your dcd. If you truly want a fresh database every time it's fine, but the accidents outnumber the intentional uses.
Where to keep them
Writing them straight into ~/.bashrc or ~/.zshrc works, but once there are a few, a separate file is easier to scan.
# ~/.bashrc [ -f ~/.docker_aliases ] && . ~/.docker_aliases
The existence check means the same dotfiles can go to a machine without Docker on it and not throw errors on login.
One last thing, true of aliases generally: they don't expand inside scripts. In bash they're off outside interactive shells, so ssh host 'dps' won't work either. Treat them as something you type by hand, and write the full command anywhere you're automating.