Skip to content

Commit 002fdc4

Browse files
Merge pull request #97 from Nemental/feat/docker-socket-protocol
feat: docker socket protocol
2 parents 9a1fa2c + a9d8ec0 commit 002fdc4

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,27 @@ Newt can integrate with the Docker socket to provide remote inspection of Docker
229229

230230
**Configuration:**
231231

232-
You can specify the Docker socket path using the `--docker-socket` CLI argument or by setting the `DOCKER_SOCKET` environment variable. On most linux systems the socket is `/var/run/docker.sock`. When deploying newt as a container, you need to mount the host socket as a volume for the newt container to access it. If the Docker socket is not available or accessible, Newt will gracefully disable Docker integration and continue normal operation.
232+
You can specify the Docker socket path using the `--docker-socket` CLI argument or by setting the `DOCKER_SOCKET` environment variable. If the Docker socket is not available or accessible, Newt will gracefully disable Docker integration and continue normal operation.
233+
234+
Supported values include:
235+
236+
- Local UNIX socket (default):
237+
>You must mount the socket file into the container using a volume, so Newt can access it.
238+
239+
`unix:///var/run/docker.sock`
240+
241+
- TCP socket (e.g., via Docker Socket Proxy):
242+
243+
`tcp://localhost:2375`
244+
245+
- HTTP/HTTPS endpoints (e.g., remote Docker APIs):
246+
247+
`http://your-host:2375`
248+
249+
- SSH connections (experimental, requires SSH setup):
250+
251+
`ssh://user@host`
252+
233253

234254
```yaml
235255
services:
@@ -243,8 +263,9 @@ services:
243263
- PANGOLIN_ENDPOINT=https://example.com
244264
- NEWT_ID=2ix2t8xk22ubpfy
245265
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
246-
- DOCKER_SOCKET=/var/run/docker.sock
266+
- DOCKER_SOCKET=unix:///var/run/docker.sock
247267
```
268+
>If you previously used just a path like `/var/run/docker.sock`, it still works — Newt assumes it is a UNIX socket by default.
248269

249270
#### Hostnames vs IPs
250271

docker/client.go

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,55 @@ type Network struct {
5353
DNSNames []string `json:"dnsNames,omitempty"`
5454
}
5555

56+
// Strcuture parts of docker api endpoint
57+
type dockerHost struct {
58+
protocol string // e.g. unix, http, tcp, ssh
59+
address string // e.g. "/var/run/docker.sock" or "host:port"
60+
}
61+
62+
// Parse the docker api endpoint into its parts
63+
func parseDockerHost(raw string) (dockerHost, error) {
64+
switch {
65+
case strings.HasPrefix(raw, "unix://"):
66+
return dockerHost{"unix", strings.TrimPrefix(raw, "unix://")}, nil
67+
case strings.HasPrefix(raw, "ssh://"):
68+
// SSH is treated as TCP-like transport by the docker client
69+
return dockerHost{"ssh", strings.TrimPrefix(raw, "ssh://")}, nil
70+
case strings.HasPrefix(raw, "tcp://"), strings.HasPrefix(raw, "http://"), strings.HasPrefix(raw, "https://"):
71+
s := raw
72+
s = strings.TrimPrefix(s, "tcp://")
73+
s = strings.TrimPrefix(s, "http://")
74+
s = strings.TrimPrefix(s, "https://")
75+
return dockerHost{"tcp", s}, nil
76+
default:
77+
// default fallback to unix
78+
return dockerHost{"unix", raw}, nil
79+
}
80+
}
81+
5682
// CheckSocket checks if Docker socket is available
5783
func CheckSocket(socketPath string) bool {
5884
// Use the provided socket path or default to standard location
5985
if socketPath == "" {
60-
socketPath = "/var/run/docker.sock"
86+
socketPath = "unix:///var/run/docker.sock"
6187
}
88+
host, err := parseDockerHost(socketPath)
89+
if err != nil {
90+
logger.Debug("Invalid Docker socket path '%s': %v", socketPath, err)
91+
return false
92+
}
93+
protocol := host.protocol
94+
addr := host.address
6295

63-
// Try to create a connection to the Docker socket
64-
conn, err := net.Dial("unix", socketPath)
96+
// ssh might need different verification, but tcp works for basic reachability
97+
conn, err := net.DialTimeout(protocol, addr, 2*time.Second)
6598
if err != nil {
66-
logger.Debug("Docker socket not available at %s: %v", socketPath, err)
99+
logger.Debug("Docker not reachable via %s at %s: %v", protocol, addr, err)
67100
return false
68101
}
69102
defer conn.Close()
70103

71-
logger.Debug("Docker socket is available at %s", socketPath)
104+
logger.Debug("Docker reachable via %s at %s", protocol, addr)
72105
return true
73106
}
74107

@@ -132,7 +165,7 @@ func ListContainers(socketPath string, enforceNetworkValidation bool) ([]Contain
132165

133166
// Create client with custom socket path
134167
cli, err := client.NewClientWithOpts(
135-
client.WithHost("unix://"+socketPath),
168+
client.WithHost(socketPath),
136169
client.WithAPIVersionNegotiation(),
137170
)
138171
if err != nil {
@@ -182,7 +215,6 @@ func ListContainers(socketPath string, enforceNetworkValidation bool) ([]Contain
182215
hostname = containerInfo.Config.Hostname
183216
}
184217

185-
186218
// Skip host container if set
187219
if hostContainerId != "" && c.ID == hostContainerId {
188220
continue

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func main() {
173173
flag.StringVar(&tlsPrivateKey, "tls-client-cert", "", "Path to client certificate used for mTLS")
174174
}
175175
if dockerSocket == "" {
176-
flag.StringVar(&dockerSocket, "docker-socket", "", "Path to Docker socket (typically /var/run/docker.sock)")
176+
flag.StringVar(&dockerSocket, "docker-socket", "", "Path or address to Docker socket (typically unix:///var/run/docker.sock)")
177177
}
178178
if pingIntervalStr == "" {
179179
flag.StringVar(&pingIntervalStr, "ping-interval", "3s", "Interval for pinging the server (default 3s)")

0 commit comments

Comments
 (0)