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>
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>
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>
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>
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>
`docker compose -f oci://<insecure-registry>/... up` failed against a
plain-HTTP registry unless --yes was passed:
failed to pull OCI resource "localhost:5000/test:interpolated":
Head "https://localhost:5000/v2/test/manifests/interpolated":
http: server gave HTTP response to HTTPS client
`up` loads the project twice. The first load goes through ToProject,
which built its OCI options from --insecure-registry correctly. Without
--yes, checksForRemoteStack then calls promptForInterpolatedVariables,
which re-loads the project through ToModel to list the interpolation
variables. That second load builds its own resource loaders via
remoteLoaders, and those passed an empty api.OCIOptions{}, dropping the
flag. Since the OCI loader always performs a network resolve, the
re-load spoke HTTPS to a plain-HTTP registry and failed before the
prompt could be shown.
The two construction sites had drifted apart, so rather than patching
the second one, both now share ProjectOptions.ociOptions(). `config`
and `viz` use the same ToModel path and are fixed as well.
Covered by an e2e case in TestPublish, which already runs an insecure
registry and an oci:// round-trip: it publishes a fixture carrying an
interpolation variable so the prompt fires, then runs `up` without
--yes and declines, asserting the re-load does not fail with
"server gave HTTP response to HTTPS client".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Domantas Petrauskas <dom.petrauskas@gmail.com>
`docker compose config --no-interpolate <service>` and
`docker compose config --variables <service>` load the raw model
without applying service filtering, so the full model is rendered
regardless of the services passed as arguments. Filtering will not
be supported on these paths, so emit a warning to make sure users
are no longer misled by silently ignored arguments.
Fixes#13614
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
maxBeforeStatusWidth used len(l.taskID) (bytes) while applyPadding
used utf8.RuneCountInString (runes). For ASCII task IDs the two
agree and no symptom surfaces, but a taskID containing multi-byte
UTF-8 chars (CJK, emoji, accented Latin) reported a width larger
than its visual columns. computeOverflow then triggered truncation
where none was needed, and truncateLongestTaskID's byte-indexed
slice could land mid-multibyte sequence, corrupting the displayed
string.
Align the two measurements on rune count.
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
In narrow terminals (e.g. tmux panes), the TTY progress UI emitted
lines wider than terminalWidth because adjustLineWidth could shrink
details and taskID but never the progress field. When progress
carried the "X.XMB / Y.YMB" size suffix, the truncation loop exited
with overflow > 0 and applyPadding's max(timerPad, 1) floor pushed
the line one char over. tmux then wrapped the line visually while
print() kept counting logical lines, desyncing aec.Up() on the next
render and producing the mangled "[+] pull X/Y" header overwriting
prior task lines.
Track the size suffix byte length on lineData and let
adjustLineWidth drop it as an intermediate truncation step before
abbreviating the taskID.
Fixesdocker/compose#13595
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
The progress UI writes to dockerCli.Err() but the auto-mode selector
was probing dockerCli.Out().IsTerminal(), introduced when the
EventProcessor was moved to the CLI layer. Any context that pipes
stdout while keeping stderr attached — `docker compose up | tee log`,
some CI wrappers, PowerShell native-command capture — silently
dropped to plain mode.
Align the detection with the stream the renderer actually targets,
restoring v4 behavior. Extract the switch into selectEventProcessor
so the auto-mode logic can be unit-tested with a real pty pair.
Fixesdocker/compose#13570
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
follow-up to 7eeb7de7a2, adding more
links now that the CLI reference for docker logs has anchors for them.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Link to the corresponding `docker container logs` equivalents, which
contain more details on the accepted formats and use.
The container logs documentation still needs some updates to provide
per-flag sections, so follow-ups can be made once those are done.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Pass the active project name as the appId query parameter on the
docker-desktop://dashboard/logs deep link, both from the post-command
hint (compose up -d, compose logs) and the interactive nav menu
('l' key during compose up). The hook subprocess re-runs compose-go's
project loader so the name matches what the parent computed; it skips
the appId when -p, -f, --project-directory, --workdir, or --env-file
is set, since the hook payload does not carry their values. docker
logs stays unfiltered: the CLI hook contract does not expose the
positional container id.
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
Docker Desktop is removing the "Enable Logs view" beta setting, so drop
the /app/settings check and rely on /features alone. With the setting
gate gone, the compose hook subprocess would print the Logs view hint
regardless of LogsTab; add a flag check in handleHook. Consolidate
engine-label discovery and feature-flag evaluation into internal/desktop.
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
Wrap the docker-desktop://dashboard/logs URL in OSC 8 escape sequences
with underline styling so it appears as a clickable link in supported
terminals. Respects NO_COLOR and COMPOSE_ANSI=never to suppress escapes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
Add CLI hooks handler to show "What's next:" hints pointing to the
Docker Desktop Logs view after `docker logs`, `docker compose logs`,
and `docker compose up -d`.
Add `l` keyboard shortcut in the `compose up` navigation menu to
open the Logs view, gated on Docker Desktop feature flag and settings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
Before this, assertion libraries were mixed, sometimes
even in the same file.
git grep -l '"gotest.tools/v3/' | wc -l
75
git grep -l '"github.com/stretchr/testify' | wc -l
24
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- Replace context.Background() with t.Context() in TestDoneDeadlockFix
- Ensures .idea files are not included in commit
Signed-off-by: maks2134 <maks210306@yandex.by>
- Replace context.Background() with context.WithCancel() in test
- Fix formatting issues (remove extra empty line)
Signed-off-by: maks2134 <maks210306@yandex.by>
Resolves race condition between main thread calling Done() and UI thread
calling printWithDimensions(). The issue was that Done() held the mutex
while sending to the done channel, but the UI thread needed the same
mutex to process the done signal.
Fixed by sending the done signal before acquiring the mutex, allowing
the UI thread to receive the signal and release any held locks.
Fixes#13639
Signed-off-by: maks2134 <maks210306@yandex.by>
Results of running the modernize command, with some minor changes
afterwards (removing the `contains` and `hasStatus` helper functions);
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
modernize -fix ./...
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also update TestDefaultNetworkSettings:
Test that the network with the highest priority is returned as
"primary" network, and other networks as extra networks.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When using OCI artifacts (e.g., `docker compose -f oci://dockersamples/welcome-to-docker up`)
on Windows, users encountered the following error:
CreateFile C:\Users\username\oci:\dockersamples\.env: The filename, directory name,
or volume label syntax is incorrect.
This issue was introduced between v5.0.0 and v5.0.1, specifically by commit 6c043929a
which fixed error handling in setEnvWithDotEnv. The bug existed in v5.0.0 but was
silently ignored due to improper error handling.
Root Cause:
-----------
The setEnvWithDotEnv function creates ProjectOptions without registering remote loaders.
Without remote loaders, the compose-go library doesn't recognize OCI paths as remote
resources. It falls through to filepath.Abs() which treats the OCI reference as a
relative path.
On Windows, filepath.Abs("oci://dockersamples/...") produces an invalid path like:
C:\Users\username\oci:\dockersamples
Windows rejects this path because colons are only valid after drive letters.
Solution:
---------
Modified setEnvWithDotEnv to detect remote config paths and skip environment loading
for them. Instead of hardcoding string checks, the fix uses the actual remote loaders'
Accept() method to determine if a config path is remote. This is more maintainable
and consistent with how the compose-go library identifies remote resources.
The function now:
- Accepts a dockerCli parameter to access remote loaders
- Uses opts.remoteLoaders(dockerCli) to get loader instances
- Checks if any loader accepts the config path using loader.Accept()
- Skips .env loading for remote configs (happens later when loaders are initialized)
- Allows normal processing for local compose files
Testing:
--------
- Added tests for OCI artifacts, Git remotes, and local paths
- Verified fix works on Windows ARM64
- All existing tests pass
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Michael Irwin <mikesir87@gmail.com>
Use t.TempDir() which automatically cleans up the temporary directory
when the test completes, eliminating the need for manual cleanup.
Go 1.14 modernization pattern.
Assisted-By: cagent
Signed-off-by: David Gageot <david.gageot@docker.com>
Replace manual context creation with t.Context() which is automatically
cancelled when the test completes.
Go 1.24 modernization pattern.
Assisted-By: cagent
Signed-off-by: David Gageot <david.gageot@docker.com>
When using --env-file=~/.env, the tilde was not expanded to the user's
home directory. Instead, it was treated as a literal character and
resolved relative to the current working directory, resulting in errors
like "couldn't find env file: /current/dir/~/.env".
This adds an ExpandUser function that expands ~ to the home directory
before converting relative paths to absolute paths.
Fixes#13508
Signed-off-by: tensorworker <tensorworker@proton.me>