Skip to content

Commit 496c91d

Browse files
Fix Docker Desktop detection via ~/.docker/run/docker.sock (#206)
1 parent d5ba448 commit 496c91d

2 files changed

Lines changed: 57 additions & 57 deletions

File tree

internal/runtime/docker.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,24 @@ func NewDockerRuntime(dockerHost string) (*DockerRuntime, error) {
5757
return &DockerRuntime{client: cli}, nil
5858
}
5959

60+
func vmSocketPaths(home string) []string {
61+
return []string{
62+
filepath.Join(home, ".docker", "run", "docker.sock"),
63+
filepath.Join(home, ".colima", "default", "docker.sock"),
64+
filepath.Join(home, ".colima", "docker.sock"),
65+
filepath.Join(home, ".orbstack", "run", "docker.sock"),
66+
filepath.Join(home, ".lima", "docker", "sock", "docker.sock"),
67+
}
68+
}
69+
6070
func findDockerSocket() string {
61-
// Lima VM: Docker socket is natively available at the standard path.
62-
// Lima sets LIMA_INSTANCE inside the VM.
71+
// Lima sets LIMA_INSTANCE inside the VM; the socket is at the standard path natively.
6372
if os.Getenv("LIMA_INSTANCE") != "" {
6473
return "/var/run/docker.sock"
6574
}
6675

6776
home, _ := os.UserHomeDir()
68-
return probeSocket(
69-
filepath.Join(home, ".colima", "default", "docker.sock"),
70-
filepath.Join(home, ".colima", "docker.sock"),
71-
filepath.Join(home, ".orbstack", "run", "docker.sock"),
72-
filepath.Join(home, ".lima", "docker", "sock", "docker.sock"),
73-
)
77+
return probeSocket(vmSocketPaths(home)...)
7478
}
7579

7680
func probeSocket(candidates ...string) string {
@@ -82,21 +86,15 @@ func probeSocket(candidates ...string) string {
8286
return ""
8387
}
8488

85-
// isVM reports whether the Docker daemon is running inside a VM (e.g., Colima, OrbStack).
89+
// isVM reports whether the Docker daemon is running inside a VM (e.g., Docker Desktop, Colima, OrbStack, Lima).
8690
// In these cases the socket is remapped inside the VM and the container sees it at
8791
// /var/run/docker.sock even if the CLI connects via a user-scoped socket path.
8892
func (d *DockerRuntime) isVM() bool {
8993
host := d.client.DaemonHost()
9094
if strings.HasPrefix(host, "unix://") {
9195
socketPath := strings.TrimPrefix(host, "unix://")
92-
// Check for known VM-based Docker socket locations
9396
home, _ := os.UserHomeDir()
94-
vmSockets := []string{
95-
filepath.Join(home, ".colima", "default", "docker.sock"),
96-
filepath.Join(home, ".colima", "docker.sock"),
97-
filepath.Join(home, ".orbstack", "run", "docker.sock"),
98-
}
99-
for _, vmSock := range vmSockets {
97+
for _, vmSock := range vmSocketPaths(home) {
10098
if socketPath == vmSock {
10199
return true
102100
}

internal/runtime/docker_test.go

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -87,45 +87,35 @@ func TestSocketPath_VMDetection(t *testing.T) {
8787
t.Cleanup(func() { _ = os.RemoveAll(home) })
8888
t.Setenv("HOME", home)
8989

90-
t.Run("colima socket exists returns remapped path", func(t *testing.T) {
91-
colimaSock := filepath.Join(home, ".colima", "default", "docker.sock")
92-
require.NoError(t, os.MkdirAll(filepath.Dir(colimaSock), 0o755))
93-
f, err := os.Create(colimaSock)
94-
require.NoError(t, err)
95-
require.NoError(t, f.Close())
96-
t.Cleanup(func() {
97-
require.NoError(t, os.Remove(colimaSock))
98-
})
99-
100-
cli, err := client.NewClientWithOpts(client.WithHost("unix://" + colimaSock))
101-
require.NoError(t, err)
102-
rt := &DockerRuntime{client: cli}
103-
assert.Equal(t, "/var/run/docker.sock", rt.SocketPath())
104-
})
90+
vmTests := []struct {
91+
name string
92+
relPath string
93+
}{
94+
{"docker desktop", ".docker/run/docker.sock"},
95+
{"colima", ".colima/default/docker.sock"},
96+
{"orbstack", ".orbstack/run/docker.sock"},
97+
{"lima host", ".lima/docker/sock/docker.sock"},
98+
}
10599

106-
t.Run("orbstack socket exists returns remapped path", func(t *testing.T) {
107-
orbstackSock := filepath.Join(home, ".orbstack", "run", "docker.sock")
108-
require.NoError(t, os.MkdirAll(filepath.Dir(orbstackSock), 0o755))
109-
f, err := os.Create(orbstackSock)
110-
require.NoError(t, err)
111-
require.NoError(t, f.Close())
112-
t.Cleanup(func() {
113-
require.NoError(t, os.Remove(orbstackSock))
100+
for _, tc := range vmTests {
101+
t.Run(tc.name+" socket returns remapped path", func(t *testing.T) {
102+
sock := filepath.Join(home, filepath.FromSlash(tc.relPath))
103+
require.NoError(t, os.MkdirAll(filepath.Dir(sock), 0o755))
104+
require.NoError(t, os.WriteFile(sock, nil, 0o600))
105+
t.Cleanup(func() { require.NoError(t, os.Remove(sock)) })
106+
107+
cli, err := client.NewClientWithOpts(client.WithHost("unix://" + sock))
108+
require.NoError(t, err)
109+
rt := &DockerRuntime{client: cli}
110+
assert.Equal(t, "/var/run/docker.sock", rt.SocketPath())
114111
})
112+
}
115113

116-
cli, err := client.NewClientWithOpts(client.WithHost("unix://" + orbstackSock))
117-
require.NoError(t, err)
118-
rt := &DockerRuntime{client: cli}
119-
assert.Equal(t, "/var/run/docker.sock", rt.SocketPath())
120-
})
121-
122-
t.Run("rootless socket exists returns actual path", func(t *testing.T) {
114+
t.Run("rootless socket returns actual path", func(t *testing.T) {
123115
// Use a non-VM socket path (short path to avoid Docker client limit)
124116
rootlessSock := "/tmp/lstk-docker.sock"
125117
require.NoError(t, os.WriteFile(rootlessSock, nil, 0o600))
126-
t.Cleanup(func() {
127-
require.NoError(t, os.Remove(rootlessSock))
128-
})
118+
t.Cleanup(func() { require.NoError(t, os.Remove(rootlessSock)) })
129119

130120
cli, err := client.NewClientWithOpts(client.WithHost("unix://" + rootlessSock))
131121
require.NoError(t, err)
@@ -161,16 +151,28 @@ func TestFindDockerSocket_LimaVM(t *testing.T) {
161151
assert.Equal(t, "/var/run/docker.sock", sock)
162152
}
163153

164-
func TestFindDockerSocket_IncludesLimaPathOnHost(t *testing.T) {
154+
func TestFindDockerSocket_ProbesVMSockets(t *testing.T) {
165155
t.Setenv("LIMA_INSTANCE", "")
166156

167-
tmpDir := t.TempDir()
168-
limaSock := filepath.Join(tmpDir, ".lima", "docker", "sock", "docker.sock")
169-
require.NoError(t, os.MkdirAll(filepath.Dir(limaSock), 0o700))
170-
require.NoError(t, os.WriteFile(limaSock, nil, 0o600))
157+
tests := []struct {
158+
name string
159+
relPath string
160+
}{
161+
{"docker desktop", ".docker/run/docker.sock"},
162+
{"colima", ".colima/default/docker.sock"},
163+
{"orbstack", ".orbstack/run/docker.sock"},
164+
{"lima host", ".lima/docker/sock/docker.sock"},
165+
}
171166

172-
t.Setenv("HOME", tmpDir)
167+
for _, tc := range tests {
168+
t.Run(tc.name, func(t *testing.T) {
169+
tmpDir := t.TempDir()
170+
sock := filepath.Join(tmpDir, filepath.FromSlash(tc.relPath))
171+
require.NoError(t, os.MkdirAll(filepath.Dir(sock), 0o700))
172+
require.NoError(t, os.WriteFile(sock, nil, 0o600))
173+
t.Setenv("HOME", tmpDir)
173174

174-
result := findDockerSocket()
175-
assert.Equal(t, limaSock, result)
175+
assert.Equal(t, sock, findDockerSocket())
176+
})
177+
}
176178
}

0 commit comments

Comments
 (0)