Setup guide · Tools and services
Docker and Docker Compose
Docker running on your machine, docker compose starting a service from a compose file, and the commands to inspect, stop and clean up containers.
Exercises that need a database, a cache, a vector store or a workflow engine run it in a container instead of installing it on your machine. Each answer project ships a compose.yaml, and one command starts Postgres, Redis, Qdrant or Temporal with the right image, ports and storage. When you're done, another command stops it, and nothing is left running in the background.
Before you start
- macOS: one of the current three major releases, Apple silicon or Intel, at least 4 GB of RAM.
- Windows: 64-bit Windows 10 22H2 or Windows 11 23H2 or newer, with hardware virtualization enabled in BIOS/UEFI and 8 GB of RAM. Docker Desktop uses WSL 2 (version 2.1.5 or later); run
wsl --updatefirst if you're unsure. - Linux: Ubuntu, Debian, Fedora or RHEL for the official packages.
- Disk: images take 100 MB to 1 GB each. Keep 10 GB free.
- Licence: Docker Desktop is free for personal use, and OrbStack has a free personal-use tier. Use either on your own machine and account.
1. Install Docker
macOS
Download Docker Desktop for your chip (Apple silicon or Intel) from the install page, open Docker.dmg and drag Docker to Applications. Start Docker.app and accept the subscription agreement; Docker won't run until you do.
Alternative: OrbStack. A lighter macOS app that runs the same docker and docker compose commands, and starts faster with less memory. Install it with Homebrew or from orbstack.dev:
brew install orbstackPick one. If you install both, OrbStack offers to copy your Docker Desktop images and volumes, and docker context use orbstack or docker context use desktop-linux chooses which one the CLI talks to.
Windows
Download Docker Desktop Installer.exe from the install page and run it. On the Configuration page, keep Use WSL 2 instead of Hyper-V selected. When it finishes, start Docker Desktop from the Start menu (it doesn't start on its own the first time) and accept the agreement.
Run the commands in this course from PowerShell or from a WSL terminal. Keep project folders inside WSL (for example ~/code) if you work there, as file access across the boundary is slow.
Linux
Install Docker Engine, the server without the desktop app. Docker's convenience script adds the official repository and installs Engine, the CLI and the Compose plugin:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.shIf you prefer to add the apt repository by hand, follow the Ubuntu guide. It ends with the same packages: docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin. Remove distro packages called docker-compose or docker-compose-v2 first, as they conflict.
To run docker without sudo, add yourself to the docker group:
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp dockerThe docker group grants root-level access to the machine, so only do this on your own computer.
2. Run your first container
docker run hello-worldDocker pulls a tiny image, runs it, prints a message that starts with Hello from Docker!, and exits. On Linux before step 1's group change, prefix it with sudo.
3. Start services with Compose
Compose comes with Docker Desktop and OrbStack, and as the docker-compose-plugin package on Linux. The command is docker compose with a space. The old docker-compose with a hyphen is the retired v1 tool; don't install it.
A compose file describes the services a project needs. Make a folder with this file:
services:
cache:
image: redis
ports:
- "6379:6379"
volumes:
- cache-data:/data
volumes:
cache-data:imageis the image on Docker Hub. No tag meanslatest, the current release.portsmapshost:container, so your code connects tolocalhost:6379.volumeskeeps data in a named volume that survives restarts anddocker compose down.
The commands you'll use, run from the folder with compose.yaml:
docker compose up -d # start everything in the background
docker compose ps # what's running, and on which ports
docker compose logs -f cache # follow one service's logs (Ctrl+C to stop)
docker compose exec cache redis-cli ping # run a command inside a container
docker compose down # stop and remove containers, keep volumes
docker compose down -v # also delete the named volumes (wipes the data)Answer projects follow the same shape. The Postgres, Redis and Qdrant tutorials each give the compose file for one service.
4. Free disk space
Images, stopped containers and build cache add up quickly. See where the space goes:
docker system dfThen clean up:
docker system prune # stopped containers, unused networks, dangling images, build cache
docker system prune -a # also every image no container is using
docker volume prune -a # unused volumes, including named ones (deletes their data)docker system prune never touches named volumes, so your databases survive it. Prune volumes only when you no longer need that data. In Docker Desktop, Settings → Resources → Advanced sets the memory the VM gets (half your RAM by default) and a disk usage limit.
Check it works
docker compose version && docker run --rm hello-world | grep "Hello from Docker"Expected output, with your current Compose version in place of the placeholder:
Docker Compose version vX.Y.Z
Hello from Docker!Troubleshooting
Cannot connect to the Docker daemon or docker: command not found. Docker Desktop or OrbStack isn't running; start the app and wait for it to say it's running. On Linux, run sudo systemctl start docker.
permission denied while trying to connect to the Docker daemon socket on Linux. You're not in the docker group yet. Run the three group commands in step 1, then open a new terminal.
Bind for 0.0.0.0:6379 failed: port is already allocated. Something else is using the port, often a Postgres or Redis you installed with Homebrew, or another project's container. Run docker ps to find and stop the container, stop the local service, or change the host side of the mapping ("6380:6379") and the port in your connection string.
Windows: Docker Desktop says WSL is too old or virtualization is off. Run wsl --update in PowerShell. If it still fails, enable virtualization (Intel VT-x or AMD-V) in your BIOS/UEFI settings.
Going further
- Postgres with pgvector, Redis and Qdrant, the services exercises start most often
- Python with uv and Node.js, pnpm and TypeScript for the code that talks to them
Sources
- Install Docker Desktop on MacDocs · DockerSupported macOS releases, the 4 GB RAM minimum and the installer steps.
- Install Docker Desktop on WindowsDocs · DockerWindows 10 22H2 / 11 23H2 requirements, WSL 2.1.5 or later, and the WSL 2 backend option.
- Install Docker Engine on UbuntuDocs · DockerThe apt repository and the `get.docker.com` convenience script, with the Compose plugin.
- Prune unused Docker objectsDocs · DockerWhat each `prune` command removes, and why named volumes survive by default.
- OrbStack quick startDocs · OrbStackThe macOS alternative to Docker Desktop, installed from the website or with Homebrew.
Exercises that use this
- Build and attack a local code runnerInfrastructure for Agents · Sandboxes for agent code
- Row-level security that fails closedInfrastructure for Agents · Secrets, identity and tenant isolation
- A self-hosted gateway with per-firm keysInfrastructure for Agents · AI gateways
- Fixed recipients and a locked sandbox in eveProduction Agent Systems · Security and prompt injection
- Trace Claude Code runs and build a per-matter budget reportProduction Agent Systems · Observability and cost
- Wire a registry with labels and trace linkagePrompt and Context Optimisation · Prompt registries and online tests
- Red-team tenant isolation (stretch)Retrieval and Knowledge Systems · Vector indexes and databases