DOCKER - 6 2 Docker Compose YAML file

This lesson walks through a docker-compose.yml template in VS Code so you know what the file is supposed to look like. The first line declares the Compose file version — for example version: "3.1". If you omit it, Compose assumes version 1, which lacks most modern features — always include the version. The three main top-level sections that follow are services, volumes and networks.

Anatomy of a compose file

YAML is whitespace-sensitive: indentation can be 2 or 4 spaces, but it must be consistent. A modern editor will tell you when it isn't. Under services you list one entry per container — Compose calls them services because each entry can be scaled to several identical containers. The service name (any string you like) becomes the DNS name used by other containers on the project's network, just like --name on docker container run.

Inside a service, you can specify the image, an alternative command, ports, volumes, environment variables and so on — basically everything you'd otherwise pass to docker container run. That's the whole point of Compose: stop typing long ad-hoc commands or maintaining brittle shell scripts. The file is readable, documented, and version-controlled.

version: "3.1"
services:
  jekyll:
    image: bretfisher/jekyll-serve
    volumes:
      - .:/site
    ports:
      - "80:4000"

Notice . (the project directory) replaces the host path you would have passed via $(pwd) on the CLI. Lists in YAML use the - prefix and plural keys (volumes, ports); single-value entries use plain key/value pairs (image).

  • services — one or more named containers; the name becomes a DNS hostname inside the project network
  • volumes — top-level section if you want named volumes
  • networks — optional; Compose creates a default network anyway
  • environment — key/value form (no dash) or list form (with dash)

A more involved example chains a MySQL container and a WordPress container, passing each service its config through environment. Anything you would write on the command line goes into Compose. Full documentation lives at docs.docker.com/compose — every key is listed with multiple examples. The next lesson turns to the Compose CLI itself.

Summary

This lesson explains the docker-compose.yml file structure and YAML syntax, which automates Docker commands by declaring all options in a structured format instead of command-line arguments. It covers the main sections (version, services, volumes, networks), YAML formatting rules (consistent indentation and list/key-value conventions), and demonstrates practical examples including Jekyll and WordPress deployments.

Key points

  • The docker-compose.yml file replaces shell scripts and repetitive docker run commands by documenting configuration in a readable YAML format
  • YAML syntax requires consistent indentation (2-4 spaces) and uses key-value pairs for single options and dash-prefixed lists for multiple items (volumes, ports, environment variables)
  • The main sections are version (default 1.0 if omitted—not recommended), services (containers), volumes, and networks; only services is mandatory
  • Service names become DNS names within Docker networks and need not match the image name—they are distinct identifiers for your containers
  • Environment variables can be specified as key-value pairs instead of repeating -e flags, improving readability and maintainability
  • Modern code editors with YAML support automatically handle indentation and formatting, making the compose file more maintainable than command-line syntax

FAQ

What happens if I don't specify a version in docker-compose.yml?

If omitted, it defaults to version 1, which is not recommended because you lose many features available in newer versions like 3.1 or higher.

How do I specify multiple volumes or ports in docker-compose.yml?

Use the plural form (volumes, ports) followed by a dash-prefixed list, where each item begins with a dash. This differs from single-value options like image or command.

Can I override the command from a Docker image using docker-compose?

Yes, you can specify an alternative command in the compose file, which overrides the command defined in the image—just like the command argument in docker run.