Docker Compose "version" Element

The version element is a relic of the past and has no bearing on how Docker Compose processes Compose files. You should delete it unless you just enjoy injecting bits of confusion into your technology projects.

A collage of docker compose files
A collage of YAML file

The first time that I opened a docker-compose.yml file everything seemed familiar. After writing hundreds of docker run.sh scripts to manage the lifecycle of containers I was able to map that format neatly into the YAML that I was staring at. Everything seemed to make sense except for the top-level version element.

After considering its purpose for a moment, is it the version of this Compose file? the version of the application that is being deployed? or is it just set by developers and users of the Compose file to keep track of changes to the Compose file? After posing these questions I decided that it would be best to head over to the official documentation to find out.

Browsing through Docker Docs I eventually arrived at "Version and name top-level element" which stated that the top-level version element is defined for backward compatibility and is for the user's information only. Docker Compose does not use it to select an exact schema for validating the Compose file, but instead always prefers the latest schema.

No matter the version specified, Compose determines whether it can fully parse the Compose file. If there are elements that are unknown, which typically occurs when a Compose file is written with elements defined by a newer version of the Specification, Compose prints a warning message (unless it is running in "loose mode").

So the version element is purely informational and has no bearing on how Compose parses Compose files. It is for the user's information only, but what information does it convey? That question led me to "History of Docker Compose".

History of Docker Compose and the Compose File Format

Nearly all Compose files that I have encountered have set the top-level version element, but the Docker Docs clearly state that it has no bearing on how Docker Compose will parse the file. So why do people bother?

In the early days of the Docker Compose project, changes to the format of Compose files were frequent. These rapid changes made it difficult to ensure compatibility between Docker Compose and the Compose file that it was processing. Since writing, and then rewriting a Compose file upon every upgrade is hardly an acceptable user experience, something had to be done.

It was at this time that the Compose file format was introduced. Its purpose was to act as a versioned schema for Compose files. All details of a Compose file format release were defined in a reference file. The Compose file format version was set in the top-level version element and Docker Compose would process the file as defined in the reference file. Below is a chart taken from Docker Docs that links to various Compose file reference files. Notice that these links lead to the "Legacy" section!

Reference fileWhat changed in this version
Version 3Version 3 updates
Version 2Version 2 updates
Version 1 (Deprecated)Version 1 updates

Why All the Changes?

If you decide to click through the above reference pages (not likely), or just encounter a bunch of Compose files (more likely), you will notice quite a few different Compose file versions. The main reasons for these changes, and incrementing the version number are as follows

  1. Syntax Compatibility: Different versions of Docker Compose may have different syntax and features. By specifying the version, you indicate which set of rules and syntax the Compose file should adhere to.
  2. Feature Availability: Newer versions of Docker Compose may introduce new features or deprecate older ones. Specifying the version ensures that you use only the features that are supported by the chosen version.
  3. Docker Compatibility: The Compose file version is associated with the Docker Engine version. Different Docker Engine versions may have different capabilities, so specifying the Compose file version helps in selecting the appropriate configuration.
  4. Documentation Reference: The version element also helps readers and users of the Compose file understand which documentation and resources to refer to for more information about the syntax and features available for that version.

Docker Compose Today and the Compose Specification

Today Docker Compose has matured. New features have slowed to a trickle and changes to the Compose file format are practically nonexistent. All of the reasons to have versioned Compose file formats are gone and with them, the need for complicated code to process different Compose file formats has been removed. The Docker Compose team has done the sensible thing and now process Compose files based on the latest standard called the Compose Specification.

Here is a link to the Compose Specification's official website and the Compose Specification itself if you care to read it. It is on a rolling release, so you will not see any top-level version elements for anything besides backward compatibility.

Do Not Add a Top-Level Version Element

All of that is to say that adding a top-level version element to your Compose files is not required and has not been for some time. You can safely delete it knowing that it is just extraneous code from an old specification. Or you can leave it to send the next engineer on a search to find out what it means.