Skip to content

fix: detect Podman container socket with Colima fallback priority#144

Closed
brianwtaylor wants to merge 2 commits intoNVIDIA:mainfrom
brianwtaylor:fix/podman-socket-detection
Closed

fix: detect Podman container socket with Colima fallback priority#144
brianwtaylor wants to merge 2 commits intoNVIDIA:mainfrom
brianwtaylor:fix/podman-socket-detection

Conversation

@brianwtaylor
Copy link
Copy Markdown
Contributor

@brianwtaylor brianwtaylor commented Mar 17, 2026

Summary

  • Extract detectContainerSocket(opts) with dependency injection for testability
  • Add Podman socket candidates: ~/.local/share/containers/podman/machine/podman.sock, /run/user/$UID/podman/podman.sock, and QEMU variant
  • Colima sockets are checked first to preserve existing behavior for current users
  • Add Podman fallback to isDockerRunning() in onboard — tries podman info if docker info fails, with a warning about --add-host=host-gateway limitations

Closes #116

Test plan

Automated Tests

npm test

New detectContainerSocket test suite (6 tests):

  1. No sockets exist → returns null
  2. Colima preferred over Podman when both exist
  3. Falls back to Podman when Colima absent
  4. Detects rootless Podman socket (/run/user/$UID/podman/podman.sock)
  5. Detects XDG Colima socket (~/.config/colima/default/docker.sock)
  6. Detects Podman QEMU socket path

Hardware Validation

Validated socket detection against real filesystem layouts:

Machine OS Runtime Socket found Path
kobe (Mac mini M2) macOS 26.2 Colima + Docker 29.2 Colima legacy ~/.colima/default/docker.sock
spark0 (DGX Spark) Ubuntu 24.04 Docker 28.5.1 native N/A (DOCKER_HOST not needed) Default /var/run/docker.sock
spark1 (DGX Spark) Ubuntu 24.04 Docker 29.1.3 native N/A Default /var/run/docker.sock

On kobe, docker ps through the detected Colima socket confirmed 4 running containers. Colima XDG path (~/.config/colima/) and Podman paths were not present, matching test expectations for a Colima-only setup.

Summary by CodeRabbit

  • New Features

    • Podman added as a fallback container runtime when Docker is unavailable.
    • Improved runtime detection to recognize Colima and additional container socket locations for better compatibility.
    • Preflight messages adjusted: runtime-specific success messages (Podman vs Docker) and a combined notice when no runtime is detected.
  • Tests

    • Added test coverage for container socket detection across multiple runtime and socket scenarios.

Extract detectContainerSocket() with dependency injection and add
Podman socket candidates (machine, rootless, QEMU). Colima sockets
are checked first to preserve existing behavior. Add Podman fallback
to isDockerRunning() with host-gateway caveat warning.

Closes #116

Signed-off-by: Brian Taylor <brian@briantaylor.xyz>
Signed-off-by: Brian Taylor <brian.taylor818@gmail.com>
@brianwtaylor brianwtaylor force-pushed the fix/podman-socket-detection branch from 0cc32c1 to 83f1196 Compare March 18, 2026 00:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Replaces Docker-only checks with multi-runtime detection: detectContainerRuntime() in bin/lib/onboard.js (returns "docker" | "podman" | null) and detectContainerSocket() in bin/lib/runner.js (returns a socket path or null). Adds tests for socket detection and exports the new runner helper.

Changes

Cohort / File(s) Summary
Onboarding runtime detection
bin/lib/onboard.js
Removed isDockerRunning(); added detectContainerRuntime() that returns `"docker"
Container socket detection & runner
bin/lib/runner.js
Added detectContainerSocket(opts) which probes prioritized socket candidate paths (Colima first, then Podman variants, including rootless/XDG/qemu paths). Uses DI overrides (home, existsSync, uid) for tests, returns first existing socket or null. Caller sets DOCKER_HOST when present. Exported from module and documented with JSDoc.
Tests for socket detection
test/runner.test.js
New test suite exercising detectContainerSocket with mocked existsSync/home/uid: no-socket, Colima vs Podman preference, Podman fallback, rootless Podman path, XDG Colima path, Podman QEMU path.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I hopped through sockets, sniffed each trail,
Colima first, then Podman’s tale.
Tests snug like carrots in a row,
Runtime found — now off we go! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: refactoring container socket detection to support both Podman and Colima with proper priority handling.
Linked Issues check ✅ Passed The PR implements the core detection improvements for issue #116 (Podman socket detection, runtime identification, and test coverage), but does not address the root cause of the host-gateway limitation mentioned in the issue.
Out of Scope Changes check ✅ Passed All changes are focused on container runtime and socket detection; no unrelated modifications were introduced.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bin/lib/onboard.js (1)

25-37: ⚠️ Potential issue | 🟡 Minor

Return runtime identity instead of a boolean to avoid Docker-only downstream behavior.

When Podman is detected, downstream flow still treats it as Docker (status text and Docker-specific remediation), because this helper only returns true/false. Please return the detected runtime and branch accordingly.

💡 Proposed fix
-function isDockerRunning() {
+function detectContainerRuntime() {
   try {
     runCapture("docker info", { ignoreError: false });
-    return true;
+    return "docker";
   } catch {
     // Podman fallback — rootless Podman can substitute for Docker
     try {
       runCapture("podman info", { ignoreError: false });
       console.log("  ⓘ Using Podman (note: --add-host=host-gateway may not resolve, see issue `#116`)");
-      return true;
+      return "podman";
     } catch {
-      return false;
+      return null;
     }
   }
 }
@@
-  if (!isDockerRunning()) {
-    console.error("  Docker is not running. Please start Docker and try again.");
+  const runtime = detectContainerRuntime();
+  if (!runtime) {
+    console.error("  Neither Docker nor Podman is running. Please start a container runtime and try again.");
     process.exit(1);
   }
-  console.log("  ✓ Docker is running");
+  console.log(`  ✓ ${runtime === "podman" ? "Podman" : "Docker"} is running`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 25 - 37, The helper isDockerRunning()
currently returns only a boolean causing Podman to be treated like Docker
downstream; change its contract to return the detected runtime identifier (e.g.,
the string "docker" when runCapture("docker info", ...) succeeds, "podman" when
runCapture("podman info", ...) succeeds) and return false (or null) when neither
is present; update any callers to branch on the returned value instead of a
boolean (use strict equality checks like returned === "podman" or === "docker")
and ensure messages/remediation use the runtime string rather than assuming
Docker; reference isDockerRunning and runCapture in your edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@bin/lib/onboard.js`:
- Around line 25-37: The helper isDockerRunning() currently returns only a
boolean causing Podman to be treated like Docker downstream; change its contract
to return the detected runtime identifier (e.g., the string "docker" when
runCapture("docker info", ...) succeeds, "podman" when runCapture("podman info",
...) succeeds) and return false (or null) when neither is present; update any
callers to branch on the returned value instead of a boolean (use strict
equality checks like returned === "podman" or === "docker") and ensure
messages/remediation use the runtime string rather than assuming Docker;
reference isDockerRunning and runCapture in your edits.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1440d786-4083-44d6-b10d-a23e7a3f2bbe

📥 Commits

Reviewing files that changed from the base of the PR and between 2a9afbc and 83f1196.

📒 Files selected for processing (3)
  • bin/lib/onboard.js
  • bin/lib/runner.js
  • test/runner.test.js

- Refactor isDockerRunning() to detectContainerRuntime() returning
  "docker", "podman", or null instead of boolean
- Caller branches on runtime name for accurate status messages
- Add JSDoc to all functions in changed files for docstring coverage
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
bin/lib/runner.js (1)

43-49: Consider moving DOCKER_HOST mutation out of module scope.

Line 43 introduces import-time side effects (process.env mutation). An explicit initializer (called by CLI entrypoints) would keep module loading pure and improve test isolation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/runner.js` around lines 43 - 49, The module currently mutates
process.env.DOCKER_HOST at import time; move that logic into an explicit
initializer function (e.g., export a function like initContainerSocket or
initializeDockerHost) so modules remain pure and tests can control
initialization. Locate the auto-detect block that calls detectContainerSocket()
and wrap its behavior into the new function, exporting it and updating CLI
entrypoints to call initializeDockerHost() at startup rather than performing the
process.env assignment during module load. Ensure the new function checks if
process.env.DOCKER_HOST is already set before assigning and returns the detected
socket or assigned value to aid testing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/runner.js`:
- Around line 21-33: The current assignment of home uses "/tmp" fallback and
then unconditionally includes home-based socket paths in the candidates array;
change this so home-based candidates are only added when a real home is
available: set home = (opts && opts.home) || process.env.HOME || null (or
undefined) instead of "/tmp", and build the candidates array by conditionally
concatenating the home-derived paths only if home is truthy (leave the Podman
/run/user/${uid}/... and other non-home paths always present); keep the existing
exists and uid logic intact and reference the home variable and candidates array
in runner.js when making this change.

---

Nitpick comments:
In `@bin/lib/runner.js`:
- Around line 43-49: The module currently mutates process.env.DOCKER_HOST at
import time; move that logic into an explicit initializer function (e.g., export
a function like initContainerSocket or initializeDockerHost) so modules remain
pure and tests can control initialization. Locate the auto-detect block that
calls detectContainerSocket() and wrap its behavior into the new function,
exporting it and updating CLI entrypoints to call initializeDockerHost() at
startup rather than performing the process.env assignment during module load.
Ensure the new function checks if process.env.DOCKER_HOST is already set before
assigning and returns the detected socket or assigned value to aid testing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eb0c88df-0bdd-4cb4-b199-d1b7a323462e

📥 Commits

Reviewing files that changed from the base of the PR and between 83f1196 and 26d5c8a.

📒 Files selected for processing (2)
  • bin/lib/onboard.js
  • bin/lib/runner.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • bin/lib/onboard.js

Comment thread bin/lib/runner.js
Comment on lines +21 to 33
const home = (opts && opts.home) || process.env.HOME || "/tmp";
const exists = (opts && opts.existsSync) || fs.existsSync;
const uid = (opts && opts.uid !== undefined) ? opts.uid : (process.getuid ? process.getuid() : 1000);

const candidates = [
// Colima (preferred — existing behavior)
path.join(home, ".colima/default/docker.sock"),
path.join(home, ".config/colima/default/docker.sock"),
// Podman machine
path.join(home, ".local/share/containers/podman/machine/podman.sock"),
`/run/user/${uid}/podman/podman.sock`,
path.join(home, ".local/share/containers/podman/machine/qemu/podman.sock"),
];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid "/tmp" fallback for home when building socket candidates.

Line 21 can produce false-positive candidate paths under /tmp when HOME is unset, which may set DOCKER_HOST to a non-user socket path. Prefer skipping home-based candidates unless a real home path is available.

Suggested patch
-  const home = (opts && opts.home) || process.env.HOME || "/tmp";
+  const home = (opts && opts.home) || process.env.HOME;
   const exists = (opts && opts.existsSync) || fs.existsSync;
   const uid = (opts && opts.uid !== undefined) ? opts.uid : (process.getuid ? process.getuid() : 1000);

-  const candidates = [
-    // Colima (preferred — existing behavior)
-    path.join(home, ".colima/default/docker.sock"),
-    path.join(home, ".config/colima/default/docker.sock"),
-    // Podman machine
-    path.join(home, ".local/share/containers/podman/machine/podman.sock"),
-    `/run/user/${uid}/podman/podman.sock`,
-    path.join(home, ".local/share/containers/podman/machine/qemu/podman.sock"),
-  ];
+  const candidates = [
+    ...(home ? [
+      // Colima (preferred — existing behavior)
+      path.join(home, ".colima/default/docker.sock"),
+      path.join(home, ".config/colima/default/docker.sock"),
+      // Podman machine
+      path.join(home, ".local/share/containers/podman/machine/podman.sock"),
+      path.join(home, ".local/share/containers/podman/machine/qemu/podman.sock"),
+    ] : []),
+    `/run/user/${uid}/podman/podman.sock`,
+  ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/runner.js` around lines 21 - 33, The current assignment of home uses
"/tmp" fallback and then unconditionally includes home-based socket paths in the
candidates array; change this so home-based candidates are only added when a
real home is available: set home = (opts && opts.home) || process.env.HOME ||
null (or undefined) instead of "/tmp", and build the candidates array by
conditionally concatenating the home-derived paths only if home is truthy (leave
the Podman /run/user/${uid}/... and other non-home paths always present); keep
the existing exists and uid logic intact and reference the home variable and
candidates array in runner.js when making this change.

@brianwtaylor
Copy link
Copy Markdown
Contributor Author

Closing — #286 supersedes this with a centralized platform.js runtime detection module that covers Podman, Colima, and Docker Desktop in a cleaner architecture.

mafueee pushed a commit to mafueee/NemoClaw that referenced this pull request Mar 28, 2026
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.

Podman compatibility: OpenShell gateway fails with 'host-gateway' on macOS

1 participant