Skip to content

fix: ensure deterministic variable interpolation (#13712)#13713

Open
yunus25jmi1 wants to merge 2 commits intodocker:mainfrom
yunus25jmi1:main
Open

fix: ensure deterministic variable interpolation (#13712)#13713
yunus25jmi1 wants to merge 2 commits intodocker:mainfrom
yunus25jmi1:main

Conversation

@yunus25jmi1
Copy link
Copy Markdown

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:

  1. compose-go fix (already pushed to https://github.com/yunus25jmi1/compose-go):

    • Added sort import to interpolation.go
    • Sort map keys before iteration in Interpolate() function
    • Sort map keys before iteration in recursiveInterpolate() function
  2. docker/compose (this PR):

    • Added replace directive to use the fixed compose-go fork

Testing

  • go build: passes
  • go vet: passes
  • go fmt: passes
  • Unit tests: pass

Related

Copilot AI review requested due to automatic review settings April 4, 2026 19:59
@yunus25jmi1 yunus25jmi1 requested a review from a team as a code owner April 4, 2026 19:59
@yunus25jmi1 yunus25jmi1 requested review from glours and ndeloof April 4, 2026 19:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 replace directive to use a forked compose-go module that includes deterministic key ordering.
  • Update go.sum to 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.

Comment on lines +3 to +4
replace github.com/compose-spec/compose-go/v2 => github.com/yunus25jmi1/compose-go/v2 v2.0.0-20260404194456-e694d656b965

Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
replace github.com/compose-spec/compose-go/v2 => github.com/yunus25jmi1/compose-go/v2 v2.0.0-20260404194456-e694d656b965

Copilot uses AI. Check for mistakes.
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>
@yunus25jmi1
Copy link
Copy Markdown
Author

Thank you for the review! You raise valid concerns about the replace directive approach.

Plan:

  1. The compose-go fix is in PR fix: ensure deterministic variable interpolation compose-spec/compose-go#860 - once merged, we will update docker/compose to use the official compose-go version
  2. This replace directive is a temporary measure to validate the fix works
  3. After compose-go PR merges, I will create a follow-up PR to:
    • Remove the replace directive
    • Update the compose-go dependency to the version with the fix

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] docker compose config --quiet produces non-deterministic result for required variables

2 participants