Compose V2 beta changes the implementation behind familiar commands
Docker Desktop 3.4 introduces the Compose V2 beta. Its Go implementation shares a Compose file model while the rollout preserves a route back to the existing executable.
A script can keep invoking docker-compose while the program handling that command changes. That is part of the rollout described in Docker's June 9 Desktop 3.4 announcement. Compose V2 arrives as a beta integrated into the Docker CLI. Docker also begins a gradual transition of the existing command, with explicit controls to opt in or revert.
The Desktop release notes describe the Go implementation as using Compose specification bindings. They say it supports most existing commands and flags, with some still to implement. Compatibility is the stated aim, but the beta designation and the incomplete flag set remain part of the announcement. The new command spelling is not a sufficient description of what has changed.
I value Docker because a build file makes environment construction repeatable. Compose extends that idea to the configuration around several services. Replacing the implementation that interprets that configuration deserves attention even when the intended result is familiar behavior.
The command and the implementation can move separately
The integrated entry point is docker compose. Existing users can try that command directly. Desktop 3.4 also supports opting into V2 through Experimental Features or by invoking docker-compose enable-v2. Docker says it will gradually make the existing docker-compose command run V2 for a small percentage of users at a time, notifying affected users.
That plan creates two independent questions for an existing script. One concerns the executable spelling it invokes. The other concerns which Compose implementation receives the request. Keeping the old spelling is useful for migration, but it does not establish that the old implementation is still running. The rollout explicitly allows the implementation to change behind that spelling.
The announcement provides docker-compose disable-v2 and the Desktop setting as ways to return to the original behavior. These controls are part of the beta deployment mechanism. They acknowledge that compatibility work is ongoing while allowing users to try the new implementation against existing projects.
This is also why a project cannot infer exact beta support from the broad phrase drop-in replacement. The release notes qualify that goal with a remaining compatibility list. The intended destination and the capabilities of the shipped beta need to be read together. A script using a particular option depends on that option's implemented behavior, not on the general direction of the project.
A shared library gives the file a common model
The Compose CLI source at v1.0.16, bundled in Desktop 3.4, depends on compose-spec/compose-go. Its dependency declaration identifies a particular revision of that library. This makes the relationship more concrete than saying both projects are written in Go. The CLI builds against code that parses and loads the shared configuration format.
The library README at that revision describes compose-go as the reference Go library for parsing and loading Compose files according to the Compose specification. It lists Compose CLI and nerdctl among its users. Shared interpretation code can therefore benefit more than one tool that accepts the format.
That does not make every backend identical. Parsing a service definition and implementing the service are different operations. The Compose CLI README describes local execution alongside Amazon ECS and Azure Container Instances integration. A common project model can feed those paths while each backend still has to translate the model into the operations its environment supports.
The practical benefit is a place to share interpretation of the input. A correction in loading or representing a field can be made in the library instead of being independently re-created in each consumer. The practical limit is that accepting a configuration structure does not prove complete support for its runtime meaning on every backend.
Loading includes environment and project selection
The command implementation shows why interpreting Compose involves more than decoding YAML. Project options include configuration paths and project name, alongside an environment file and project directory. The CLI passes those choices to the shared library when constructing a project.
The registered flags include --file, --project-name, --env-file and --project-directory. The loader setup also includes operating system environment variables and the dotenv handling options. These inputs help determine the resulting project. Two invocations that read the same visible service definition can still differ because the surrounding options differ.
This is a useful way to understand compatibility testing without reducing it to a list of commands to run. A project is the result of file selection and environment interpretation as well as the service entries. A replacement implementation needs to preserve the relevant meaning of those inputs for the workflow it claims to support.
Profiles add another selection step. The source registers --profile, reads COMPOSE_PROFILES from the loaded environment and applies the accumulated profiles to the project. When the user names services directly, it also obtains those services' profiles before applying the selection. The effective set of services is therefore part of project construction.
I find that source-level separation useful because it identifies where disagreements can occur. A file can parse successfully while the wrong working directory, environment or service selection produces a different project. Shared model code makes those steps visible and gives maintainers a more specific place to discuss a compatibility problem.
Local execution is the next Compose implementation
The tagged CLI README describes the local command as the next major version of Compose. It says Go makes sharing functionality with the Docker CLI and other Docker libraries easier. It also identifies greater task parallelism and BuildKit by default as characteristics of the new local implementation. These are implementation choices beneath the familiar service configuration.
BuildKit selection is particularly relevant when a Compose project builds images. Reusing the Dockerfile does not mean the build engine is unchanged. The README establishes the new default, but it does not provide a benchmark for a particular project. Any performance claim about that project would need evidence beyond the architectural change itself.
The launch announcement also introduces docker compose ls for listing Compose applications and docker compose cp for copying between a service container and the local filesystem. Listing makes the project a visible object in the command interface. Copying expresses a file transfer in terms of the service container a Compose user is managing.
Those additions fit the integration into the Docker CLI. The user can stay within the same command family while working with a project and its containers. They also show that the effort includes new behavior, alongside the work of reproducing the previous command set. Compatibility and extension are both present in this beta.
Command adaptation has observable behavior too. The source wraps operations in a cancellable context where needed and registers handlers for interrupt and termination signals. It maps a cancelled operation to a status error with exit code 130. This is relevant to scripts because process completion is another part of the command contract. Producing the intended containers is only one observable result of an invocation. Its response to interruption and the exit status a caller receives also determine how surrounding automation behaves. The source gives those cases explicit handling instead of treating them as incidental effects of the new implementation language.
Desktop includes both Compose generations
Desktop 3.4's upgrade list includes standalone Docker Compose 1.29.2 as well as Compose CLI 1.0.16. Keeping those components distinct helps explain the available fallback. A Desktop version identifies the bundle, while a command and its selected implementation identify which behavior a particular invocation uses.
The release also introduces volume creation and deletion through the Dashboard and displays whether volumes are in use. Those controls concern persistent data managed around the containers. They complement project-oriented commands, but the existence of a new interface does not change the need to understand which service owns the data and which operation removes it.
For the Compose beta, the central change is that the shared file model now supports a Go implementation integrated into the Docker CLI. Docker is rolling that implementation out through both a new entry point and a compatibility route for the existing one. The remaining option gaps and the supplied revert controls define the limits of the release available today.