Commit graph

5898 commits

Author SHA1 Message Date
Branislav Osif
fc860cbd1f fix: ignore one-off container events in up monitor
`up --abort-on-container-exit` tore down the project when a one-off
container created by `docker compose run` exited. The container list
built in monitor.Start already excludes one-off containers via
oneOffFilter(false), but the event subscription did not, and the only
guard on incoming events is the service label, which a one-off
container inherits from the service it was run from.

Regression since v2.39.0 (last unaffected release is v2.38.2), and a
recurrence of docker/compose-cli#1955, fixed there by
docker/compose-cli#1987.

Signed-off-by: Branislav Osif <brano@osif.digital>
2026-08-12 16:02:25 +02:00
dependabot[bot]
be30fb4dd1 build(deps): bump docker/github-builder/.github/workflows/bake.yml
Bumps the docker-actions group with 1 update: [docker/github-builder/.github/workflows/bake.yml](https://github.com/docker/github-builder).


Updates `docker/github-builder/.github/workflows/bake.yml` from 1.15.0 to 1.16.0
- [Release notes](https://github.com/docker/github-builder/releases)
- [Commits](27ade872c1...a492c6d04f)

---
updated-dependencies:
- dependency-name: docker/github-builder/.github/workflows/bake.yml
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-12 15:37:23 +02:00
dependabot[bot]
971f9560ce build(deps): bump github.com/docker/buildx from 0.36.0 to 0.36.1
Bumps [github.com/docker/buildx](https://github.com/docker/buildx) from 0.36.0 to 0.36.1.
- [Release notes](https://github.com/docker/buildx/releases)
- [Commits](https://github.com/docker/buildx/compare/v0.36.0...v0.36.1)

---
updated-dependencies:
- dependency-name: github.com/docker/buildx
  dependency-version: 0.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-12 15:33:54 +02:00
dependabot[bot]
17a35fcc51 build(deps): bump github.com/moby/buildkit from 0.32.1 to 0.32.2
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.32.1 to 0.32.2.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.32.1...v0.32.2)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-version: 0.32.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-12 15:27:44 +02:00
Endika Iglesias
832673c8e4 test(watch): cover the permission branches as root
CI runs the tests as root, where the unreadable-directory test is always
skipped. Extract the WalkDir callbacks and inject the watch registration
so a synthetic permission error can drive those branches instead.

Signed-off-by: Endika Iglesias <endika2@gmail.com>
2026-08-11 14:10:40 +02:00
Endika Iglesias
fb543842d8 fix(watch): skip unreadable directories instead of failing the watch
Signed-off-by: Endika Iglesias <endika2@gmail.com>
2026-08-11 14:10:40 +02:00
Guillaume Lours
7bc2630b65 fix(config): resolve service environment when computing --hash
Containers are created from a project whose service environment is
resolved (env_file merged into environment), but since v2.22.0 `config
--hash` skipped that resolution, so hashes diverged from the
com.docker.compose.config-hash label for services using env_file.

Resolve the environment of the hashed services only, so a broken
env_file or platforms on an unrelated service still doesn't prevent
hashing, and honor --no-env-resolution as an escape hatch.

Fixes #14001

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-11 08:37:13 +02:00
Guillaume Lours
5573bd2601 fix(watch): stop pruning every dangling image of the project
pruneDanglingImagesOnRebuild probed the name-keyed built-images map with
an image ID, so the spare-check never matched and every dangling image
carrying the project label was removed on each rebuild with --prune —
not just the superseded ones. Match dangling IDs against the map's
values (the freshly built image IDs) instead.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-11 08:05:14 +02:00
dependabot[bot]
6a59c98de1 build(deps): bump github/codeql-action/upload-sarif
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.4 to 4.37.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](f205ea1c33...d1ba80a13d)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-11 08:02:48 +02:00
Ricardo Branco
668d81d4ec test: Set stop_signal to SIGTERM in nginx-based services
The official nginx images set STOPSIGNAL to SIGQUIT which dumps core.
Set it to SIGTERM to avoid dumping core on e2e tests when containers
running "sleep infinity" are stopped.

Signed-off-by: Ricardo Branco <rbranco@suse.de>
2026-08-10 12:42:02 +02:00
dependabot[bot]
fc209c8f44 build(deps): bump github/codeql-action/upload-sarif
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.3 to 4.37.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](e4fba868fa...f205ea1c33)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-10 08:32:14 +02:00
Eric Wyles
d95ff5b3d5 Reuse bridge image version in e2e tests
Signed-off-by: Eric Wyles <23637493+ericwyles@users.noreply.github.com>
2026-08-06 16:00:08 +02:00
Eric Wyles
1b76c732f2 Update pkg/bridge/convert.go
Co-authored-by: Guillaume Lours <705411+glours@users.noreply.github.com>
Signed-off-by: Eric Wyles <23637493+ericwyles@users.noreply.github.com>
2026-08-06 16:00:08 +02:00
Eric Wyles
c25474844c fix(bridge): skip pulling default image references for build-only services
Signed-off-by: Eric Wyles <23637493+ericwyles@users.noreply.github.com>
2026-08-06 16:00:08 +02:00
dependabot[bot]
5d69dabbda build(deps): bump github.com/moby/moby/client from 0.5.0 to 0.5.1
Some checks failed
ci / validate (lint) (push) Has been cancelled
ci / validate (validate-docs) (push) Has been cancelled
ci / validate (validate-go-mod) (push) Has been cancelled
ci / validate (validate-headers) (push) Has been cancelled
ci / binary (push) Has been cancelled
ci / bin-image-test (push) Has been cancelled
ci / test (push) Has been cancelled
ci / e2e (plugin, oldstable) (push) Has been cancelled
ci / e2e (standalone, oldstable) (push) Has been cancelled
ci / e2e (plugin, stable) (push) Has been cancelled
ci / e2e (standalone, stable) (push) Has been cancelled
merge / bin-image-prepare (push) Has been cancelled
merge / module-image (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
zizmor / zizmor (push) Has been cancelled
ci / binary-finalize (push) Has been cancelled
ci / coverage (push) Has been cancelled
ci / release (push) Has been cancelled
merge / bin-image (push) Has been cancelled
Bumps [github.com/moby/moby/client](https://github.com/moby/moby) from 0.5.0 to 0.5.1.
- [Release notes](https://github.com/moby/moby/releases)
- [Changelog](https://github.com/moby/moby/blob/v0.5.1/CHANGELOG.md)
- [Commits](https://github.com/moby/moby/compare/v0.5.0...v0.5.1)

---
updated-dependencies:
- dependency-name: github.com/moby/moby/client
  dependency-version: 0.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-04 11:54:40 +02:00
Guillaume Lours
ef61d7410a bump buildkit v0.32.1
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-03 15:53:30 +02:00
Guillaume Lours
1fa0590a9a bump buildx v0.36.0 and buildkit v0.32.0
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-03 14:56:34 +02:00
Guillaume Lours
cda9f2044f fix(oci): fetch artifact layers from blobs endpoint, not via Resolve
Pulling an oci:// resource resolved each layer digest through the
registry manifests endpoint, which answers 500 when the digest points
to a non-manifest blob. containerd v2.3.0+ (pulled in by buildx v0.36
and buildkit v0.32) no longer falls back to the blobs endpoint unless
manifests returned 404, so publish/pull of compose artifacts broke.
Fetch layers directly with the descriptors already listed in the
manifest instead of resolving them again.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-03 14:56:34 +02:00
Guillaume Lours
15f2fedf3d chore(deps): github.com/docker/buildx v0.36.0-rc2, buildkit v0.32.0-rc2
Test the upcoming buildx and BuildKit releases ahead of GA.
buildx v0.36.0-rc2 requires Go >= 1.26.3, so the go directive
moves from 1.25.9 to 1.26.3.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-03 14:56:34 +02:00
dependabot[bot]
7e20f3bb26 build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.3 to 2.4.4.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](4eaacf0543...2d1146689b)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 14:22:14 +02:00
dependabot[bot]
e9a26b62b5 build(deps): bump docker/docker-agent-action/.github/workflows/review-pr.yml
Bumps the docker-actions group with 1 update: [docker/docker-agent-action/.github/workflows/review-pr.yml](https://github.com/docker/docker-agent-action).


Updates `docker/docker-agent-action/.github/workflows/review-pr.yml` from 2.0.2 to 2.0.3
- [Release notes](https://github.com/docker/docker-agent-action/releases)
- [Commits](774b6e0e60...baf90543d8)

---
updated-dependencies:
- dependency-name: docker/docker-agent-action/.github/workflows/review-pr.yml
  dependency-version: 2.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 12:03:00 +02:00
dependabot[bot]
b7c346a72e build(deps): bump actions/stale from 10.4.0 to 11.0.0
Bumps [actions/stale](https://github.com/actions/stale) from 10.4.0 to 11.0.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](1e223db275...4391f3da66)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 11.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 12:02:29 +02:00
Sebastiaan van Stijn
2ff87b74b5 update to go1.26.5
go1.26.5 (released 2026-07-07) includes security fixes to the crypto/tls
and os packages, as well as bug fixes to the compiler, the runtime, the
go command, and the net, os, and syscall packages. See the Go 1.26.5
milestone on our issue tracker for details;

- https://github.com/golang/go/issues?q=milestone%3AGo1.26.5+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.26.4...go1.26.5

From the security announcement:

We have just released Go versions 1.26.5 and 1.25.12, minor point releases.

These releases include 2 security fixes following the security policy:

- os: Root escape via symlink plus trailing slash

  On Unix systems, opening a file in an os.Root improperly
  followed symlinks to locations outside of the Root when
  the final path component of the a path is a symbolic link
  and the path ends in /.

  For example, root.Open("symlink/") would open "symlink"
  even when "symlink" is a symbolic link pointing outside of the root.

  On Unix, openat(fd, path, O_NOFOLLOW) will follow symlinks
  in path when path ends in a /. Root failed to account for
  this behavior, permitting paths with a trailing / to escape.
  It now properly sanitizes the path parameter provided to openat.

  hanks to Mundur for reporting this issue.

  This is CVE-2026-39822 and Go issue https://go.dev/issue/79005.

- crypto/tls: Encrypted Client Hello privacy leak

  he Encrypted Client Hello implementation would leak the pre-shared key
  dentities during the handshake, allowing a passive network observer who can
  ollect handshakes to de-anonymize the hostname of the server, even when ECH was
  eing used.

  Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.

  This is CVE-2026-42505 and Go issue https://go.dev/issue/79282.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-08-03 11:46:47 +02:00
Guillaume Lours
ea82c55224 ci: publish images to Docker Hub using OIDC
Replace the long-lived DOCKERPUBLICBOT PAT with short-lived tokens
minted through the Docker Hub OIDC connection, using the
registry-identities input of the github-builder bake workflow.

The connection rulesets cover both triggers of this workflow
(refs/heads/main and refs/tags/v*) for compose-bin and
compose-desktop-module.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-08-03 11:08:09 +02:00
Sebastiaan van Stijn
2fa7a294ab chore(deps): bump github.com/moby/go-archive v0.3.2
Some checks failed
ci / validate (lint) (push) Has been cancelled
ci / validate (validate-docs) (push) Has been cancelled
ci / validate (validate-go-mod) (push) Has been cancelled
ci / validate (validate-headers) (push) Has been cancelled
ci / binary (push) Has been cancelled
ci / bin-image-test (push) Has been cancelled
ci / test (push) Has been cancelled
ci / e2e (plugin, oldstable) (push) Has been cancelled
ci / e2e (standalone, oldstable) (push) Has been cancelled
ci / e2e (plugin, stable) (push) Has been cancelled
ci / e2e (standalone, stable) (push) Has been cancelled
merge / bin-image-prepare (push) Has been cancelled
merge / module-image (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
zizmor / zizmor (push) Has been cancelled
ci / binary-finalize (push) Has been cancelled
ci / coverage (push) Has been cancelled
ci / release (push) Has been cancelled
merge / bin-image (push) Has been cancelled
full diff: https://github.com/moby/go-archive/compare/v0.3.1...v0.3.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-31 20:05:21 +02:00
dependabot[bot]
9846e27450 build(deps): bump docker/github-builder/.github/workflows/bake.yml
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Bumps the docker-actions group with 1 update: [docker/github-builder/.github/workflows/bake.yml](https://github.com/docker/github-builder).


Updates `docker/github-builder/.github/workflows/bake.yml` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/docker/github-builder/releases)
- [Commits](3415a188ca...27ade872c1)

---
updated-dependencies:
- dependency-name: docker/github-builder/.github/workflows/bake.yml
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-31 11:48:48 +02:00
Guillaume Lours
e371eabc5d bump go-archive to version v0.3.0
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-30 18:35:54 +02:00
Guillaume Lours
970e58381c bump compose-go to version v2.14.0
Some checks failed
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
docs-upstream / docs-yaml (push) Has been cancelled
docs-upstream / validate (push) Has been cancelled
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-30 12:06:04 +02:00
dependabot[bot]
5f878da948 build(deps): bump github.com/moby/buildkit from 0.31.1 to 0.31.2
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.31.1 to 0.31.2.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.31.1...v0.31.2)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-version: 0.31.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-30 12:02:00 +02:00
dependabot[bot]
f2a6f94379 build(deps): bump actions/checkout from 7.0.0 to 7.0.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](9c091bb21b...3d3c42e5aa)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-30 11:41:08 +02:00
Guillaume Lours
d8370536f0 fix: tolerate missing env file on scale, watch and shell completion
Follow-up to #13603: scale, watch and shell completion loaded the
project without any tolerance option, so a missing env_file on a
service not involved in the operation aborted the command, while
up/exec/ps already tolerate this since #13156 and #13603.

Mirror the WithServices pattern: load with WithoutEnvironmentResolution
and resolve the environment once the project has been reduced to the
selected services, so targeted services still get their env_file
validated. Completion only needs names and never resolves. This also
aligns the config hash of scale-created containers with up-created
ones.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-30 11:38:47 +02:00
Guillaume Lours
7bdc31c5de fix(config): apply config flags to --services/--volumes/--networks/--models/--hash
The runServices, runVolumes, runNetworks, runModels and runHash paths
called ProjectOptions.ToProject directly, bypassing the configOptions
wrapper that applies --no-consistency, --no-interpolate, --no-normalize,
--no-path-resolution, --profile filtering and env_file discarding.
Restore the variadic wrapper (mirroring configOptions.ToModel) and route
the five call sites through it.

Regression introduced by b80bb0586 (LoadProject API migration).

Fixes #13974

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-30 11:38:20 +02:00
Guillaume Lours
367f1d5701 fix(cp): return non-nil Content from dry-run CopyFromContainer
The caller in pkg/compose/cp.go unconditionally defers
res.Content.Close() once the call succeeds. The dry-run client
returned a zero-value result with a nil Content reader, so
`docker compose cp --dry-run <ctr>:<path> <dst>` panicked with a
nil pointer dereference. Return an empty NopCloser instead, matching
the pattern already used for the other stream results in this file.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-30 11:37:49 +02:00
Nicolas De Loof
aa518b9c3a Force-pull pre_start hook images under pull_policy: always
addPreStartHookPulls skipped any hook image already present locally,
regardless of pull policy. As a result a service with pull_policy: always
had its own image force-pulled on every up while its pre_start hook images
were left stale — diverging from both the service image and the `pull`
command path (which already re-pulls hooks under always).

Skip the "already present" shortcut when the parent service is
pull_policy: always, so hook images get the same force-pull treatment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-30 10:40:06 +02:00
Nicolas De Loof
1cc5120af8 Dedup pre_start hook images against service and each other
Address review feedback on pre_start hook image resolution:

1. GetDependentImages now skips a hook image equal to the service image
   (resolved via GetImageNameOrDefault), so `config --images` no longer
   prints a duplicate line and pullRequiredImages no longer schedules a
   redundant pull for it.

2. pullRequiredImages (up/create path) now dedups dependent images by
   reference via a `scheduled` set, so several hooks/services sharing the
   same missing image don't schedule concurrent redundant pulls. The hook
   pass moved to a helper (addPreStartHookPulls) to keep complexity in check.

3. The `pull` command no longer skips hook images under `pull_policy: build`.
   A hook image is a registry image that can't be built, so only `never`
   justifies skipping it — making `pull` consistent with the `up` path.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-30 10:40:06 +02:00
Nicolas De Loof
c9266e6297 Resolve pre_start hook images alongside service images
pre_start hooks run as ephemeral init containers with their own image
(ServiceHook.Image), but that image was ignored by image resolution:
`config --images` didn't list it, `pull` didn't fetch it, and `up` failed
at runtime with "No such image" when it wasn't already present locally.

Add a GetDependentImages helper that returns a service's pre_start hook
images, and use it wherever service images are collected/pulled:
getLocalImagesDigests, pullRequiredImages (up path), the pull command, and
`config --images`. Hook images inherit the parent service pull policy.

post_start/pre_stop hooks run via ExecCreate inside the service container
and never use hook.Image, so they are intentionally out of scope.

Digest resolution/locking (--resolve-image-digests / --lock-image-digests)
is not covered: compose-go's WithImagesResolved only resolves service.Image
(needs an upstream change), and the --lock-image-digests override merges
pre_start by concatenation, which would duplicate hooks.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-30 10:40:06 +02:00
dependabot[bot]
1c7930e91a build(deps): bump github/codeql-action/upload-sarif
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.0 to 4.37.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](99df26d4f1...e4fba868fa)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-29 11:21:20 +02:00
dependabot[bot]
e19f3c634d build(deps): bump github.com/docker/cli
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 29.6.1+incompatible to 29.6.2+incompatible.
- [Commits](https://github.com/docker/cli/compare/v29.6.1...v29.6.2)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 29.6.2+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-28 14:34:22 +02:00
Guillaume Lours
38d12f505f docs: require dated AI_AGENT_DISCLOSURE.md, drop committed copy
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
AI_AGENT_DISCLOSURE.md was merged into the repository by accident as
part of a reconcile change (44ac2c94e). With the file permanently
present, the AGENTS.md instruction to "add" it became a no-op and
AI-prepared pull requests no longer carried any disclosure signal.

Remove the committed copy and change the instruction to add the file
with the current date, or refresh the date when the file is already
present, so every AI-prepared change includes the disclosure in its
diff.

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-28 10:18:38 +02:00
Nicolas De Loof
e1131ad655 refactor(reconcile): aggregate observed resources, resolve conflicts in reconcile
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
collectObservedState indexed networks/volumes by compose label into a
single-valued map, so two live resources sharing a label (e.g. a leftover
after a rename) collided and the "winner" depended on the daemon's list
order — a nondeterministic `up` (spurious create/recreate events, possible
churn) on subsequent runs.

Make collection lossless and move the selection into the reconciler:

- ObservedState.Networks/Volumes become map[string][]Observed*: collection
  records every label-sharing resource and makes no premature choice.
- selectNetwork/selectVolume deterministically pick the resource matching
  the desired name (else the lexicographically smallest), returning the
  others as orphans.
- reconcile resolves the observed state once (resolveObserved) into
  single-valued resolvedNetworks/resolvedVolumes used everywhere, and warns
  about orphans instead of acting on them — they are left untouched because
  removing them could drop data or break unrelated workloads.

Adds selection unit tests, a collector aggregation test and a reconcile
conflict test (deterministic no-op + orphan warning across list orders).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-27 14:56:25 +02:00
Nicolas De Loof
ba2358c98c feat(reconcile): best-effort old-network removal on rename
A network rename does not require removing the old network — the new one
has a different name and is created independently. Yet the old removal
could block the whole operation: NetworkRemove fails when non-Compose
containers are still attached, and CreateNetwork depended on it.

Split the rename path from the same-name divergence path:

- Rename: CreateNetwork no longer depends on RemoveNetwork; the container
  migration proceeds regardless. RemoveNetwork is marked best-effort and,
  if the network is still in use (reported as a conflict), is skipped with
  a warning instead of failing. Any other error (transport, Moby API) is
  still propagated.
- Same-name divergence keeps the mandatory remove-before-create ordering.

Adds an Operation.BestEffort flag, honored by execRemoveNetwork, plus
reconcile and executor tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-27 14:56:25 +02:00
Nicolas De Loof
d764fee527 fix(reconcile): retry network create on conflict, keep owned config-hash
Address review findings on the network reconcile migration:

- createNetwork now treats a NetworkCreate conflict as success. A
  concurrent `docker compose up|run` can create the same network in the
  TOCTOU window between the observed-state snapshot and the create call;
  the previous ensureNetwork retried on conflict, the plain create must
  not fail hard.

- discoverUnmanagedNetworks/Volumes preserve the config-hash when the live
  resource is owned by this project (project label present, key label
  absent — e.g. written by an older Compose) so genuine divergence is
  still detected. For resources we don't own the hash stays empty and they
  are reused untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-27 14:56:25 +02:00
Nicolas De Loof
f3647227b6 feat(reconcile): migrate containers on network rename
Treat a network rename (observed.Name != desired.Name) as a recreation
rather than an additive create: the old network is removed, the new one
created, and attached containers are migrated onto it (reconnected), so
they no longer stay on the previous network until recreated for another
reason.

Networks carry no data, so removing the previous network — instead of
leaving it dangling alongside the new one under the same compose label —
is safe and keeps subsequent runs deterministic. This is a marginal
behavior change from previous Compose releases (which created the new
network and left the old attachments in place) in exchange for the more
logical outcome.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-27 14:56:25 +02:00
Nicolas De Loof
0723f71021 feat(reconcile): model network lifecycle in the plan
Mirror the volume reconciliation work (#13962) for networks: move network
divergence detection and recreation out of the imperative pre-reconcile
path (ensureNetwork/resolveOrCreateNetwork/removeDivergedNetwork) into the
reconciliation plan.

- reconcileNetworks now owns creation of missing networks and, for a
  network whose config-hash diverged, an explicit recreation sequence
  (no user confirmation: recreating a network is not destructive):
  stop containers -> disconnect -> remove network -> create network ->
  reconnect containers. Attached containers keep their identity (they are
  reconnected, not recreated), matching the previous behavior. If a
  container is independently recreated by reconcileContainers, its removal
  is ordered after the reconnect so they don't race.
- Renaming a network creates the new one additively and leaves the old one
  untouched.
- collectObservedState discovers legacy/unlabeled networks by name and
  records them as unmanaged matches (empty config-hash) so the reconciler
  reuses them untouched; ownership warnings move to warnUnmanagedNetworks.
  checkExternalNetworks keeps external-network validation/resolution.
- execCreateNetwork now issues a plain createNetwork; the imperative
  ensureNetwork/resolveOrCreateNetwork/removeDivergedNetwork and the
  connect/disconnect helpers are removed.

Adds reconcile, observed-state and executor tests covering network
create/diverge/rename, the entangled diverge+recreate case, legacy
by-name discovery and the ownership warnings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-27 14:56:25 +02:00
Max Proske
54e0373f1c Tolerate missing env file on runtime commands
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
Signed-off-by: Max Proske <max@mproske.com>
2026-07-27 09:20:14 +02:00
Guillaume Lours
37dea37d67 fix(config): pin type:image volume sources and pre_start hook images
Some checks failed
ci / validate (lint) (push) Has been cancelled
ci / validate (validate-docs) (push) Has been cancelled
ci / validate (validate-go-mod) (push) Has been cancelled
ci / validate (validate-headers) (push) Has been cancelled
ci / binary (push) Has been cancelled
ci / bin-image-test (push) Has been cancelled
ci / test (push) Has been cancelled
ci / e2e (plugin, oldstable) (push) Has been cancelled
ci / e2e (standalone, oldstable) (push) Has been cancelled
ci / e2e (plugin, stable) (push) Has been cancelled
ci / e2e (standalone, stable) (push) Has been cancelled
merge / bin-image-prepare (push) Has been cancelled
merge / module-image (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
zizmor / zizmor (push) Has been cancelled
ci / binary-finalize (push) Has been cancelled
ci / coverage (push) Has been cancelled
ci / release (push) Has been cancelled
merge / bin-image (push) Has been cancelled
Rely on compose-go WithImagesResolved, which now resolves dependent
images — `type: image` volume sources and pre_start hook images —
with its already-digested guard, per-call memoization and
sibling-service detection (compose-spec/compose-go#894, #899), rather
than duplicating resolution logic CLI-side. The interpolated path gets
this for free; --no-interpolate maps the raw model onto a
pseudo-project keyed by service names to reuse the same resolution,
and --lock-image-digests keeps type:image volumes in its output.
pre_start hooks can't be carried into the lock override (hook lists
are appended on merge), so generating a lock warns that hook images
stay unpinned there.
As a side effect, `compose publish` now fails fast on unresolvable
dependent images.

Fixes #13827

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
2026-07-24 15:33:21 +02:00
Nicolas De Loof
69b2f69d31 fix(reconcile): migrate containers to the renamed volume within the same up
Some checks are pending
ci / validate (lint) (push) Waiting to run
ci / validate (validate-docs) (push) Waiting to run
ci / validate (validate-go-mod) (push) Waiting to run
ci / validate (validate-headers) (push) Waiting to run
ci / binary (push) Waiting to run
ci / binary-finalize (push) Blocked by required conditions
ci / bin-image-test (push) Waiting to run
ci / test (push) Waiting to run
ci / e2e (plugin, oldstable) (push) Waiting to run
ci / e2e (standalone, oldstable) (push) Waiting to run
ci / e2e (plugin, stable) (push) Waiting to run
ci / e2e (standalone, stable) (push) Waiting to run
ci / coverage (push) Blocked by required conditions
ci / release (push) Blocked by required conditions
merge / bin-image-prepare (push) Waiting to run
merge / bin-image (push) Blocked by required conditions
merge / module-image (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
zizmor / zizmor (push) Waiting to run
The additive rename path created the new volume but kept the old name in
the observed state, so hasVolumeMismatch never fired: existing containers
stayed on the old volume while fresh replicas mounted the new one
(split-brain), and later runs picked a nondeterministic winner between the
two equally labelled volumes.

Rewrite the observed volume name to the desired one after planning the
"renamed" create, so reconcileContainers migrates the existing containers
onto the new volume in the same up — restoring parity with the old
ensureVolume path — while still leaving the old volume and its data intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-23 16:17:43 +02:00
Nicolas De Loof
601be0f094 fix(reconcile): preserve backward compatibility for legacy volumes
Two edge regressions from the switch to a label-scoped observed state,
both reported against the old ensureVolume path:

- A same-named volume created manually or by another project (no compose
  label) was invisible to the observed state, so a VolumeCreate was
  planned on every up: a hard failure if the driver differed, spurious
  Creating/Created events otherwise. collectObservedState now discovers
  such volumes by name (pre-label Compose semantics) and records them as
  unmanaged matches with an empty config-hash, so the reconciler reuses
  them untouched. The ownership warnings move to warnUnmanagedVolumes,
  driven off the observed state; checkVolumes shrinks to external-only
  validation (checkExternalVolumes).

- Renaming a volume hit the diverged path and, with up -y, deleted the
  old volume and its data (VolumeHash includes Name), where it previously
  just created the new one. When observed.Name != desired.Name the volume
  is now created additively, leaving the old one untouched, with no prompt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-23 16:17:43 +02:00
Nicolas De Loof
b45991bf47 fix(reconcile): remove volumes_from consumers before volume recreation
servicesUsingVolume only matched services mounting the volume directly, so
a service reaching it through volumes_from was not stopped/removed before
RemoveVolume. Docker materializes the inherited mount on the consumer's
container, so its removal would fail with "volume in use". Compute the
transitive volumes_from closure so every container referencing the volume
is removed first. (network_mode/ipc/pid: service:x share namespaces, not
mounts, and are intentionally excluded.)

Also reassign the result of Labels.Add in createVolume: it mutates in
place only when the map is non-nil, so discarding the return would drop
the config-hash label for a volume with no CustomLabels.

Addresses review feedback: documents why observed.Containers is cleared
without touching the observedContainersByService hashing snapshot, and
strengthens the cascade tests to assert the full plan ordering.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-23 16:17:43 +02:00
Nicolas De Loof
44ac2c94e9 feat(reconcile): model volume recreation in the plan
Move volume divergence detection and recreation out of the imperative
pre-reconcile path (ensureVolume/removeDivergedVolume) and into the
reconciliation plan, activating the dormant planRecreateVolume seam.

A diverged volume now produces an explicit, forward-only sequence:
stop containers -> remove containers -> remove volume -> create volume
-> create containers. Container re-creation is delegated to
reconcileContainers (affected services are cleared from the observed
snapshot so they are scheduled fresh, gated on the CreateVolume node),
and the recreation cascades to namespace/volume-sharing dependents.

User confirmation (recreate, data will be lost) is consulted while
building the plan via reconciler.prompt; declining leaves the volume
untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-07-23 16:17:43 +02:00