Skip to content

Docker Commands

Compose is invoked as docker compose (two words). That is the V2 plugin, and it is what ships with Docker Desktop and with the Docker Engine packages. The standalone docker-compose binary is V1: Docker’s own documentation describes installing it as “not recommended and is only supported for backward compatibility purposes”, and a current installation has no such binary at all. Older material — including anything written before 2023 — uses the hyphenated form; translate it by replacing the hyphen with a space.

  • Start an existing container: docker start kafka
  • Follow a container’s log: docker logs -f kafka
  • Get a shell inside a running container: docker exec -it <container> /bin/sh (use /bin/bash where the image has it). This is not SSH — there is no daemon, no login and no credentials involved; it starts a new process inside the container’s namespaces.
  • Inspect an image’s metadata: docker image inspect mongo
  • Keep a container alive that would otherwise exit immediately: docker run -d debian tail -f /dev/null
  • Override the entrypoint: docker run --entrypoint "/bin/ls" debian -al /root
  • Override the entrypoint and stay attached: docker run -it --entrypoint "/bin/bash" <image> -i
  • Run and clean up on exit: docker run --rm -p 8080:8080 base-image
  • List containers: docker container ls -a (docker ps -a is the older spelling of the same thing).
  • Build and start everything in the background: docker compose up -d --build
  • Stop the services but keep the containers: docker compose stop
  • Stop and remove the containers and the networks the project created: docker compose down. Volumes are kept unless -v (--volumes) is added, which also removes the named volumes declared in the file.
  • List the services in the project: docker compose ps
  • Open a shell in a service container: docker compose exec broker bash

With Confluent Platform’s quick-start compose file running, the Control Center is served at http://localhost:9021, and the ksqlDB CLI connects to the ksqlDB server over the compose network:

docker compose exec ksqldb-cli ksql http://ksqldb-server:8088

Note the service name: the product was renamed from KSQL to ksqlDB, and the images and compose services are ksqldb-server and ksqldb-cli. Compose files from the KSQL era also start a zookeeper service; Apache Kafka 4.0 removed ZooKeeper entirely in favour of KRaft, so a current cluster has no ZooKeeper container to shell into.

From the directory containing the Dockerfile:

docker build [-t <tag name>] [--no-cache] .

The trailing . is the build context — the directory whose contents are sent to the builder — not a flag, and it is required.

The prune commands are the supported way to reclaim space. Each one reports what it will remove and asks for confirmation unless given -f:

docker container prune # remove all stopped containers
docker image prune # remove dangling images (add -a for all unused images)
docker volume prune # remove anonymous volumes (add -a for all unused volumes)
docker network prune # remove unused networks
docker system prune # stopped containers, unused networks, dangling images, build cache

docker system prune does not touch volumes: adding --volumes brings them in, and -a widens the image sweep from dangling images to every image no container is using.

The older hand-rolled equivalents still work and are occasionally useful when a filter is needed that prune does not offer:

  • docker kill $(docker ps -q) — kill every running container
  • docker rm $(docker ps -a -q) — delete every stopped container
  • docker rmi $(docker images -q -f dangling=true) — remove untagged (dangling) images. -q is the quiet option, which prints ids only, and -f applies a filter.
  • docker rmi $(docker images -q) — delete every image
  • docker volume rm $(docker volume ls -f dangling=true -q) — remove dangling volumes. The management command is docker volume, singular.
docker login --username=yourhubusername
docker images
docker tag bb38976d03cf yourhubusername/repo_name:tag
docker push yourhubusername/repo_name:tag

Tag and push the same reference. A reference written without a tag means :latest, so pushing a repository name on its own pushes that one tag; --all-tags pushes every local tag of the image.

  • docker history <image> shows the layers and the instruction that created each one, which is how to recover the ARG values baked in at build time.
  • docker inspect <image-id> shows the image configuration, including the default ENV values that will apply before the container starts.