fix: ensure deterministic variable interpolation (#13712)#13713
fix: ensure deterministic variable interpolation (#13712)#13713yunus25jmi1 wants to merge 4 commits intodocker:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses non-deterministic “missing required variable” interpolation errors by switching Docker Compose to a compose-go variant that sorts map keys during interpolation, making error reporting deterministic across runs.
Changes:
- Add a
replacedirective to use a forked compose-go module that includes deterministic key ordering. - Update
go.sumto reflect the forked compose-go module version/checksums.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| go.mod | Replaces upstream compose-go with a forked module version to pick up deterministic interpolation behavior. |
| go.sum | Removes upstream compose-go sums and adds sums for the forked compose-go module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
go.mod
Outdated
| replace github.com/compose-spec/compose-go/v2 => github.com/yunus25jmi1/compose-go/v2 v2.0.0-20260404194456-e694d656b965 | ||
|
|
There was a problem hiding this comment.
The new replace directive pins compose-go to a personal fork (github.com/yunus25jmi1/compose-go). This creates a supply-chain/maintenance risk (availability/review process is now tied to an external fork) and it also won’t help downstream modules that import github.com/docker/compose/v5 as a dependency (replace directives are only honored in the main module). Prefer updating to an upstream github.com/compose-spec/compose-go/v2 commit/release once the fix is merged, or (if this must be temporary) add a TODO comment with a tracking link and a clear plan to remove the replace.
| replace github.com/compose-spec/compose-go/v2 => github.com/yunus25jmi1/compose-go/v2 v2.0.0-20260404194456-e694d656b965 |
This fixes the non-deterministic behavior when multiple required
variables (e.g., ${TIMEZONE:?}, ${TRAEFIK_ACME_PATH:?}) are missing.
Go's map iteration order is randomized, causing different error messages
to be reported on each run.
Changes:
- Add replace directive to use fixed compose-go fork
- The compose-go fix adds sort.Strings(keys) before map iteration
to ensure consistent error reporting
Fixes: docker#13712
Signed-off-by: Md Yunus <admin@yunuscollege.eu.org>
|
Thank you for the review! You raise valid concerns about the replace directive approach. Plan:
The current approach allows testing the fix while waiting for upstream compose-go merge. I will add a TODO comment with a tracking link as suggested. |
TODO: Remove replace once compose-go#860 is merged See: compose-spec/compose-go#860 Signed-off-by: Md Yunus <admin@yunuscollege.eu.org>
Resolve merge conflict in go.sum - keep the replace directive to compose-go fork for deterministic variable interpolation fix. Signed-off-by: Md Yunus <admin@yunuscollege.eu.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
go.mod
Outdated
| // TODO: Remove replace once compose-go#860 is merged. See: https://github.com/compose-spec/compose-go/pull/860 | ||
|
|
||
| replace github.com/compose-spec/compose-go/v2 => github.com/yunus25jmi1/compose-go/v2 v2.0.0-20260404194456-e694d656b965 |
There was a problem hiding this comment.
The new replace points at a personal fork (github.com/yunus25jmi1/compose-go). That creates a supply-chain and long-term availability risk (module can change/disappear, and builds become dependent on a non-org-owned repo). Prefer pinning to an upstream commit/branch in compose-spec/compose-go if possible, or hosting the temporary fork under an org-owned namespace (e.g., github.com/docker/...) until the upstream PR is merged and a release is cut.
Removes the replace directive pointing to a personal fork (supply-chain risk). Uses official compose-go v2.10.2 from upstream. Note: The deterministic interpolation fix from compose-go#860 is not yet merged upstream. Once merged, we can update to the version with the fix. Signed-off-by: Md Yunus <admin@yunuscollege.eu.org>
|
Hi @ndeloof @glours and docker/compose-maintainers, I've updated this PR to address the supply-chain risk concern raised in the review. The replace directive pointing to the personal fork (github.com/yunus25jmi1/compose-go/v2) has been removed, and we're now using the official compose-go v2.10.2 from upstream. This eliminates the supply-chain risk of depending on a personal fork. Note: The deterministic interpolation fix from compose-spec/compose-go#860 is not yet merged upstream. Once that PR is merged and released, we'll need to update to the version that includes the fix. Please review the updated changes. |
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@yunus25jmi1 What do you want us to review? PR is empty |
Description
This fixes the non-deterministic behavior when multiple required variables (e.g., ${TIMEZONE:?}, ${TRAEFIK_ACME_PATH:?}) are missing in docker-compose.yaml.
Root Cause
Go's map iteration order is randomized. When iterating over service environment variables or volumes during interpolation, different keys can be processed in different orders on each run. This causes the error message for missing required variables to vary between runs.
Fix
The fix adds sort.Strings(keys) before map iteration in the compose-go library's interpolation.go file to ensure deterministic processing order.
Changes:
compose-go fix (already pushed to https://github.com/yunus25jmi1/compose-go):
docker/compose (this PR):
Testing
Related
docker compose config --quietproduces non-deterministic result for required variables #13712