You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(docker): resolve docker by absolute path on macOS spawn; honest docker_available (#696) (#697)
* fix(docker): resolve docker by absolute path on macOS spawn; honest docker_available (#696)
On macOS, Docker Desktop installed the default way (without the optional,
admin-gated "install CLI tools" step) leaves the docker CLI only inside the
app bundle at /Applications/Docker.app/Contents/Resources/bin/docker, which is
not on any standard PATH dir. mcpproxy spawned isolated servers with bare
`docker` on a sanitized PATH that omits the bundle dir, so docker was
unresolvable at spawn (~20x `command not found: docker`), while
`upstream_servers list` misreported `docker_available: true`.
- Spawn (root cause): setupDockerIsolation resolves docker to an absolute path
via shellwrap.ResolveDockerPath (mirroring newDockerCmd) before shell-wrapping;
falls back to bare "docker" only when resolution fails.
- Enhanced spawn PATH (defense in depth): add the Docker Desktop bundle bin dir
on darwin; split the candidate list into a pure, unit-testable function.
- Honest availability: MCPProxyServer.resolveDockerStatus and
Runtime.IsDockerAvailable report available only when the CLI is resolvable AND
`docker info` succeeds — no bare-docker fallback that would misreport. Surface
the resolved binary as docker_status.docker_path; diagnostics.checkDockerDaemon
reports unavailable with an actionable error when unresolvable.
- Diagnostics: formatRecentStderr leads a single actionable "Docker CLI not
found" hint on `command not found` and collapses identical consecutive lines
into "… (repeated N×)", replacing the 20-line wall.
macOS-specific paths guarded behind runtime.GOOS=="darwin"; Linux/Windows
unaffected. Docs updated for docker_path, telemetry counter semantics, and a
new troubleshooting entry.
Related #696
* fix(docker): accept /c (Windows cmd) in cidfile insertion + regression test
insertCidfileIntoShellDockerCommand checked shellArgs[n-2]=="-c" to
distinguish a shell-wrapped command string from an unrecognised format.
On Windows with cmd.exe (no bash), WrapWithUserShell returns ["/c", cmdStr]
so the flag is "/c", not "-c"; the guard rejected it and silently skipped
cidfile insertion, breaking TestSetupDockerIsolationCidfileInsertionWithAbsolutePath
on windows-latest CI.
Accept both flags ("-c" and "/c") so cidfile insertion works on every
platform. Add TestInsertCidfileWindowsCmdFormat (pure unit, no real Docker)
to pin the Windows cmd format.
Copy file name to clipboardExpand all lines: docs/docker-isolation.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,7 +123,7 @@ Starting in this release, MCPProxy emits a one-time warning in the main log when
123
123
124
124
When anonymous telemetry is enabled, MCPProxy reports two Docker-related counters at daily cadence:
125
125
126
-
-`server_docker_available_bool` — whether the host has a reachable Docker daemon. Probed with `docker info --format {{.ServerVersion}}`and cached for up to 15 minutes (5 minutes when the previous probe failed, so a late Docker-Desktop launch is picked up promptly).
126
+
-`server_docker_available_bool` — whether Docker is actually invocable. Reported `true` only when the `docker` CLI is **resolvable to an absolute path***and*`docker info --format {{.ServerVersion}}`succeeds (it does **not** fall back to a bare `docker` PATH probe, which could misreport availability when the binary is only inside the macOS app bundle — see issue #696). Cached for up to 15 minutes (5 minutes when the previous probe failed, so a late Docker-Desktop launch is picked up promptly).
127
127
-`server_docker_isolated_count` — how many of your configured stdio servers are **configured** for isolation, i.e. servers for which `ShouldIsolate()` returns true. This is a configuration metric, not a count of running containers; it goes to zero whenever the global flag is off regardless of per-server opt-ins.
128
128
129
129
## Runtime Detection
@@ -245,6 +245,23 @@ docker stats
245
245
- Check container logs for specific error messages
246
246
- Verify network access for package repositories
247
247
248
+
**`command not found: docker` on macOS (Docker Desktop installed):**
249
+
- Docker Desktop installed the default way leaves the `docker` CLI only inside
250
+
the app bundle at `/Applications/Docker.app/Contents/Resources/bin/docker` —
251
+
it is **not** on a standard `PATH` dir unless you ran the optional,
252
+
admin-gated "install CLI tools" step. When mcpproxy is launched from a
253
+
LaunchAgent / tray, the captured login-shell `PATH` may omit this directory.
254
+
- mcpproxy resolves the `docker` binary to its **absolute path** before
255
+
spawning an isolated server (and also adds the bundle bin dir to the enhanced
256
+
spawn `PATH`), so isolation works even without the CLI-tools step. If you
257
+
still see this error, confirm the binary exists at the bundle path above, or
258
+
run Docker Desktop's "install CLI tools".
259
+
-`upstream_servers list` reports `docker_status.docker_path` (the resolved
260
+
binary) and reports `docker_status.available` / per-server `docker_available`
261
+
as `true`**only** when the CLI is actually resolvable *and*`docker info`
262
+
succeeds. A `false` value with `docker_path: ""` means the CLI could not be
263
+
resolved on the spawn path.
264
+
248
265
## Security Considerations
249
266
250
267
Docker isolation provides strong security boundaries but consider:
// Honest availability (#696): if the CLI can't be resolved to an
195
+
// absolute path, Docker-isolated servers can't spawn it. Report
196
+
// unavailable with an actionable error rather than probing a bare
197
+
// "docker" that is not the binary used for spawning.
198
+
status.Available=false
199
+
status.Error="Docker CLI not found on PATH or well-known install locations (on macOS the CLI ships at /Applications/Docker.app/Contents/Resources/bin/docker even without the optional CLI-tools step)"
200
+
s.logger.Debugw("Docker CLI not resolvable; reporting docker unavailable", "error", resolveErr)
"Docker isolation is enabled but Docker daemon is not available",
3075
+
"Docker isolation is enabled but the Docker CLI is not resolvable / the daemon is not reachable",
3073
3076
"Servers configured for isolation will fail to start",
3074
-
"Install Docker or disable isolation in config",
3077
+
"Install Docker (on macOS the CLI ships at /Applications/Docker.app/Contents/Resources/bin/docker even without the optional CLI-tools step), or disable isolation in config",
0 commit comments