Compose Specification: the document behind multi-container Compose files
The Compose specification
At a glance
- What is it?
- The normative spec that Docker Compose, Podman Compose, Nerdctl and others implement, kept as numbered Markdown chapters and assembled into one generated spec.md.
- Who is it for?
- This repository is a document, not a tool, and the useful thing about it is that you can read the whole normative text in an afternoon without running anything. The numbered chapter files are the source of truth and `spec.md` is a generated artifact, so the right way to settle a question is to find the chapter that owns it, `05-services.md` for a service key or `14-include.md` for file inclusion, and then read the merge and interpolation rules that sit between them.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly Dockerfile, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the specification sets out to define
The README opens by stating the purpose in one line: the Compose specification establishes a standard for the definition of multi-container, platform-agnostic applications. That is a narrower and more technical claim than the word Compose usually carries in conversation. It is not a tutorial and not an implementation. It is the agreed description of what a Compose file means, written so a file can be handed between a local development machine and a cloud hosting service without being rewritten.
The use cases section explains why that matters, and the three it names are worth reading in order. The first is development tools, where an implementation can add local niceties such as volume binding and live reload while keeping the same application model, and where platform features the specification expects, configs and secrets, get mocked with local resources during development. The second is Kubernetes deployment: the README credits Kompose and Okteto Stacks with translating the simpler Compose model into Kubernetes API payloads so the Compose file stays the source of truth across both environments. The third is cloud providers, whose proprietary orchestrators otherwise force users to learn a custom configuration format.
The metadata table at the bottom of the README says the status is work in progress and the document was created on 2020-01-02, which lines up with the Docker Compose v2 era. The repository is licensed Apache 2.0 with the license in the `LICENSE` file, has a homepage at compose-spec.io, and was last pushed on 2026-09-19.
The numbered chapter files are the real table of contents
The tree is the most informative part of the repository, because it shows the specification's structure at the level of individual normative concerns. From `00-overview.md` through `15-profiles.md`, each file is one chapter, and the naming is consistent enough to navigate by.
`01-status.md` states the document's own maturity. `02-model.md` describes the application model. `03-compose-file.md` defines the file itself. `04-version-and-name.md` covers the version field and the project name. `05-services.md` is the largest subject, the service definition. Then come `06-networks.md` and `07-volumes.md`, followed by the two platform-resource chapters, `08-configs.md` and `09-secrets.md`.
The last six chapters are the ones people usually need while writing a real file. `10-fragments.md` covers reusable fragments, `11-extension.md` the extension mechanism for platform-specific features, `12-interpolation.md` variable substitution, `13-merge.md` the rules for combining multiple Compose files, `14-include.md` pulling in other files, and `15-profiles.md` conditional activation. Having interpolation, merge and include as separate chapters is a deliberate signal: those are where ambiguity in Compose files actually lives, and a specification that buried them would be a worse specification.
Alongside the chapters sit `AGENTS.md`, `CONTRIBUTING.md`, `GOVERNANCE.md`, `OWNERS.md`, `CHANGELOG.md` and `VISION.md`. The presence of an agent instruction file in a document repository is a small modern detail, and it tells you the project expects contributions from automated tooling as well as people.
How spec.md is assembled from the chapters
The repository generates one combined document rather than publishing the chapters separately, and the build lives in a Dockerfile with a specific and slightly odd shape. It starts from `node:16.1` as a generator stage, installs `@adobe/jsonschema2md` globally, copies the `schema` directory in, and runs `jsonschema2md -d /schema/ -e json` to produce reference documentation from the JSON schema. A second stage copies that output into a scratch image.
The specification assembly stage runs on Alpine and concatenates the Markdown files in numeric order into `spec.md`:
cat head.md > spec.md
cat 01-status.md >> spec.md
cat 03-compose-file.md >> spec.md
cat 15-profiles.md >> spec.mdThose four lines are the whole idea, and the ordering constraint is the thing to understand. If you add a chapter, you have to add its `cat` line in the right place, because the order of the files is the order of the document. The `FROM --platform=${BUILDPLATFORM}` declaration on that stage is the other detail worth noting: the concatenation happens on the build machine's architecture rather than the target's, which matters for anyone building this on Apple silicon.
One line in that list writes to a stray file called `spec.m` as well as to `spec.md`. Shell redirections are processed left to right, so the content still reaches `spec.md`, but it is the kind of inconsistency you notice by reading rather than by running, and it is a fair signal of how rarely the Dockerfile is exercised by hand.
A build target that fails when the committed spec drifts
The most interesting thing in this repository is not a chapter. It is the `spec-validate` stage, a self-checking build. The stage copies the generated `spec.md` out of the build stage, mounts the build context, and runs a shell script that deletes the local `spec.md`, copies the generated one into place, and then asks git whether anything changed:
rm spec.md
cp /out/spec.md ./spec.md
git add -A
git status --porcelain -- ./spec.mdIf the committed file and the generated file differ in any byte, the build exits non-zero and prints a message telling you to update with `make spec`. A documentation repository that would otherwise drift quietly between its chapters and its published form instead treats drift as a build error. That is a small design decision with a large effect on how sixteen chapters stay consistent with each other.
The Makefile wraps this for contributors, and the two targets you care about are generation and validation. It also handles a Windows detail, setting a drive prefix when the OS variable is `Windows_NT`, because the build output path is an absolute path handed to Docker's local output.
make spec
make validate-specA third target is worth knowing about, because it keeps the JSON schema in step with the Go implementation by pulling it from another repository:
curl -L https://raw.githubusercontent.com/compose-spec/compose-go/refs/heads/main/schema/compose-spec.json -o schema/compose-spec.jsonDrawing the schema from compose-go rather than maintaining it here is a deliberate dependency direction, and it means the schema, not the prose, is the machine-readable artifact an implementation actually validates a file against.
Docker Compose as the reference implementation, and the seven others
The README names Docker Compose as the reference implementation of the specification, then lists seven others that implement it. The list reads like a map of where Compose files turn up in practice: Kompose for Kubernetes, Nerdctl for containerd, Okteto Compose, Docker Cloud Integrations, Podman Compose, Google Cloud Run Compose, and a Compose bridge for the Unified Defense Stack.
Two entries on that list change how you read the specification. Podman Compose means a Compose file you test locally against Podman may behave differently from one run by Docker Compose, and the spec is what the two are supposed to share. Google Cloud Run Compose means a Compose file can be a deployment artifact for a managed platform, which is the strongest evidence that the document's platform-agnostic goal is doing real work rather than aspirational phrasing.
The rest of the repository supports the site rather than the spec. There is a `Gemfile` and `Gemfile.lock`, a `_config.yml` and a `_layouts/` directory, which is Jekyll rendering the Markdown for the web version, plus `build.md`, `deploy.md` and `develop.md` describing the site pipeline. Contributing happens on GitHub with issues tracking bugs and actionable items, and longer discussion happens on a Google group mailing list. Notably there are no releases published: this is a document that changes through commits, and the changelog is the record.
What a reader should use the document for, and what it cannot answer
The practical value here is a canonical answer to a specific question. When a Compose file misbehaves and the fix is disputed, the chapter that owns the feature settles the argument. Build contexts, service dependency conditions, config object mounting and merge precedence all have normative text, and the merge chapter in particular resolves the class of bug where two files each say something reasonable and the combination surprises you.
What the specification deliberately does not contain is implementation behaviour. It does not tell you how a runtime streams container logs, how it builds images, how it negotiates registry credentials, or how it implements watch and live reload. Those are the real differences between Docker Compose, Podman Compose and a cloud provider's Compose support, and collapsing them would defeat the purpose of a platform-agnostic model. The README makes the same point from the other direction when it says platform-specific features are added through Compose extensions or a dedicated configuration file alongside the Compose file.
The caveat to carry around is the status. The README's own metadata says work in progress, and a specification describing itself that way in 2026 has been in motion for six years. The generated `spec.md` is what implementations target, the chapters are what people read, and the gap between those two artifacts is precisely what the `spec-validate` build target exists to close.
Editorial conclusion
This repository is a document, not a tool, and the useful thing about it is that you can read the whole normative text in an afternoon without running anything. The numbered chapter files are the source of truth and `spec.md` is a generated artifact, so the right way to settle a question is to find the chapter that owns it, `05-services.md` for a service key or `14-include.md` for file inclusion, and then read the merge and interpolation rules that sit between them. What the repository does not settle is implementation detail: nothing here says how a given runtime streams logs, builds images or authenticates to a registry, because those choices differ deliberately between Docker Compose, Podman Compose and cloud provider offerings.
Frequently asked questions
What is the Compose Specification and who follows it?
It is the normative document defining the Compose file model for multi-container, platform-agnostic applications, hosted at compose-spec.io. Docker Compose is named as the reference implementation, and Kompose, Nerdctl, Okteto Compose, Docker Cloud Integrations, Podman Compose and Google Cloud Run Compose also implement it.
Is the compose-spec repository the same thing as Docker Compose?
No. This repository holds no application code and publishes no releases; it is the written specification, licensed Apache 2.0, with Docker Compose as the reference implementation living in a separate repository. Its language shows as Dockerfile because the document is assembled by a build that concatenates the numbered Markdown chapters.
Where does spec.md come from in the compose-spec repository?
It is generated. The Dockerfile concatenates `head.md` and the numbered chapter files from `01-status.md` through `15-profiles.md` in order, and the Makefile target `make spec` rebuilds it. A separate `make validate-spec` target fails the build if the generated file differs from the committed one.
Which chapter covers Compose file merging?
`13-merge.md` owns it, alongside `12-interpolation.md` for variable substitution and `14-include.md` for pulling in other files. Merge, interpolation and include get separate chapters because that is where ambiguity in Compose files concentrates.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/compose-spec-compose-spec)