Skip to content

fix(cluster): refuse Docker Compose 2.37.1 to 2.38.x - #19

Merged
Mearman merged 2 commits into
mainfrom
fix/compose-rerun-recreates
Sep 26, 2026
Merged

Mearman merged 2 commits into
mainfrom
fix/compose-rerun-recreates

Conversation

@Mearman

@Mearman Mearman commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Closes #5

The recreation comes from Compose itself, not from anything the role does. On ubuntu-latest (Compose v2.38.2, Engine 28.0.4, overlay2 storage, not the containerd image store) I captured each node container's labels before and after the rerun in the hosted scenario. The config hash and the image ID were identical across the two runs; the only difference was the com.docker.compose.image label, which was empty on the containers the first run created. docker compose up --dry-run before the rerun showed Recreate for all three nodes, and the module's result for the rerun showed the same. After that recreate the label is filled in, and a third up leaves the containers alone.

The same thing happens with plain docker compose up -d twice on any service that has build: (a one-line FROM busybox Dockerfile is enough), with no Ansible involved. A service that only pulls its image is unaffected, because Compose fills the label in from the pulled image. Running the role's own Compose file twice under a range of Compose releases on ubuntu-latest:

  • 2.36.2, 2.37.0: second up keeps the container
  • 2.37.1, 2.37.3, 2.38.2: second up recreates it, third keeps it
  • 2.39.0, 2.39.4, 2.40.3, 5.0.0: second up keeps it
  • 2.38.2 with COMPOSE_BAKE=false, or with docker compose build run before up: keeps it

So it is the Bake build path. Before 2.39.0 Compose keyed Bake's build result by service name instead of image name, so the code that stamps the image ID on the new container found nothing. That was fixed in docker/compose#13047, released in 2.39.0. I did not reproduce the Docker Desktop case from the issue, so I can't say why 2.38.2 behaved there.

In a fleet this means one restart of every node on the run after the k3s image is built or rebuilt (a new host, or a k3s or Tailscale version bump), not on every run, but that is still every etcd member restarting at once.

Since both the fault and its fix are in Compose, the role now checks docker compose version as its first task and fails before touching the host on 2.37.1 up to but not including 2.39.0, saying why and to upgrade. I first wrote this as a plain minimum of 2.39.0, but a check-mode run against the fleet showed one host on Docker Desktop's Compose 2.29.7, which predates the fault and would have been refused for nothing, so the check refuses only the faulty range. The role README documents it and the top-level README's prerequisites point there.

For CI, the mesh workflow gains two matrix entries: the hosted scenario on 2.39.0, whose rerun check shows the first fixed release keeps every node running, and a compose_faulty scenario on 2.38.2 that asserts the role refuses it with that message and writes nothing to the node directory. The existing scenarios stay on 5.5.1.

The diagnostics and the version matrix above ran from a scratch branch that has since been deleted. Check-mode runs of the fleet's site.yml with this branch's collection on the two reachable hosts reported no change to the k3s Compose task on either; the only change reported was the kubernetes client virtualenv task on one host, which reports the same with the currently released collection.

@Mearman
Mearman force-pushed the fix/compose-rerun-recreates branch from 7c945eb to 5126229 Compare September 26, 2026 06:50
Compose 2.37.1 to 2.38.x build a service's image through Bake and key
the build result by service name rather than image name
(docker/compose#13047, fixed in 2.39.0), so the container created in
the same `up` gets an empty com.docker.compose.image label.
The next `up` sees that label differ from the image ID and recreates
the container, restarting every k3s node on the run after the one that
built the k3s image.
The config hash and the image ID are unchanged between runs; the label
is the only difference.

The role now reads `docker compose version` before touching the host
and fails with an explanation on a release in that range.
Releases before it do not have the fault, so they stay accepted.
A compose_faulty scenario runs the cluster role under Compose 2.38.2
and asserts it refuses before writing to the host.
The hosted scenario also runs on 2.39.0, the first fixed release, so
the rerun check covers it.
@Mearman
Mearman force-pushed the fix/compose-rerun-recreates branch from 5126229 to 556786c Compare September 26, 2026 06:51
@Mearman Mearman changed the title fix(cluster): refuse Docker Compose older than 2.39.0 fix(cluster): refuse Docker Compose 2.37.1 to 2.38.x Sep 26, 2026
@Mearman
Mearman marked this pull request as ready for review September 26, 2026 06:59
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ⚠️ Failed 2026-09-26T07:00:18.039572Z 556786c Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Mearman
Mearman merged commit 224dfac into main Sep 26, 2026
18 checks passed
@Mearman
Mearman deleted the fix/compose-rerun-recreates branch September 26, 2026 07:00
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.3.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rerunning the cluster role recreates node containers with Compose v2.38.2 on Docker Engine 28

1 participant