Skip to content

Commit a3199a6

Browse files
authored
Fix server port when network mode is host (#2353)
Docker networking works differently depending on whether it's running inside a VM or on the (linux) host itself, with VM-based installations like Docker Desktop not supporting `host` network. What happens is that the port is exposed on the VM rather than the actual host. Note that this is the case for linux running Docker Desktop. On the other hand, Docker Engine installations work just fine on linux, but we were still configuring the Proxy to try to connect to the wrong port. This is PR assumes that * all linux installations run docker engine * all non-linux installations run on VMs Fixes #2317
1 parent c864276 commit a3199a6

File tree

4 files changed

+59
-11
lines changed

4 files changed

+59
-11
lines changed

pkg/container/docker/client.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -291,20 +291,33 @@ func (c *Client) DeployWorkload(
291291
return 0, nil
292292
}
293293

294+
firstPortInt, err := extractFirstPort(options)
295+
if err != nil {
296+
return 0, err // extractFirstPort already wraps the error with context.
297+
}
294298
if isolateNetwork {
295299
// just extract the first exposed port
296-
firstPortInt, err := extractFirstPort(options)
297-
if err != nil {
298-
return 0, err // extractFirstPort already wraps the error with context.
299-
}
300300
hostPort, err = c.ops.createIngressContainer(ctx, name, firstPortInt, attachStdio, externalEndpointsConfig,
301301
permissionProfile.Network)
302302
if err != nil {
303303
return 0, fmt.Errorf("failed to create ingress container: %v", err)
304304
}
305305
}
306306

307-
return hostPort, nil
307+
// NOTE: this is a hack to get the final port for the workload.
308+
// The intended behavior is the following
309+
// * if network is "bridge" (default) and network isolation is not enabled, then
310+
// the Proxy should use the Docker assigned port
311+
// * if network is "bridge" (default) and network isolation is enabled, then
312+
// the Proxy should use the egress container port
313+
// * if network is "host", then the Proxy should use the MCP server port
314+
//
315+
// The last case is not supported in VM-based installations like Docker Desktop.
316+
// Unfortunately, there's no reliable way to know if the user is using a VM-based
317+
// installation and we assume that Linux installations are Docker Engine installations.
318+
finalPort := calculateFinalPort(hostPort, firstPortInt, permissionConfig.NetworkMode)
319+
320+
return finalPort, nil
308321
}
309322

310323
// ListWorkloads lists workloads
@@ -1314,6 +1327,9 @@ func (c *Client) createContainer(
13141327
if err != nil {
13151328
return "", NewContainerError(err, "", fmt.Sprintf("failed to create container: %v", err))
13161329
}
1330+
if resp.Warnings != nil {
1331+
logger.Debugf("Container creation warnings: %v", resp.Warnings)
1332+
}
13171333

13181334
// Start the container
13191335
err = c.api.ContainerStart(ctx, resp.ID, container.StartOptions{})
@@ -1386,10 +1402,21 @@ func (c *Client) createDnsContainer(ctx context.Context, dnsContainerName string
13861402
return dnsContainerId, dnsContainerIP, nil
13871403
}
13881404

1389-
func (c *Client) createMcpContainer(ctx context.Context, name string, networkName string, image string, command []string,
1390-
envVars map[string]string, labels map[string]string, attachStdio bool, permissionConfig *runtime.PermissionConfig,
1391-
additionalDNS string, exposedPorts map[string]struct{}, portBindings map[string][]runtime.PortBinding,
1392-
isolateNetwork bool) error {
1405+
func (c *Client) createMcpContainer(
1406+
ctx context.Context,
1407+
name string,
1408+
networkName string,
1409+
image string,
1410+
command []string,
1411+
envVars map[string]string,
1412+
labels map[string]string,
1413+
attachStdio bool,
1414+
permissionConfig *runtime.PermissionConfig,
1415+
additionalDNS string,
1416+
exposedPorts map[string]struct{},
1417+
portBindings map[string][]runtime.PortBinding,
1418+
isolateNetwork bool,
1419+
) error {
13931420
// Create container configuration
13941421
config := &container.Config{
13951422
Image: image,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build linux
2+
3+
package docker
4+
5+
func calculateFinalPort(hostPort int, firstPortInt int, networkName string) int {
6+
if networkName == "host" {
7+
return firstPortInt
8+
}
9+
return hostPort
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build !linux
2+
3+
package docker
4+
5+
func calculateFinalPort(hostPort int, _ int, _ string) int {
6+
return hostPort
7+
}

pkg/transport/http.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,12 @@ func (t *HTTPTransport) Start(ctx context.Context) error {
321321

322322
// Create the transparent proxy
323323
t.proxy = transparent.NewTransparentProxy(
324-
t.host, t.proxyPort, t.containerName, targetURI,
325-
t.prometheusHandler, t.authInfoHandler,
324+
t.host,
325+
t.proxyPort,
326+
t.containerName,
327+
targetURI,
328+
t.prometheusHandler,
329+
t.authInfoHandler,
326330
t.remoteURL == "",
327331
t.remoteURL != "",
328332
string(t.transportType),

0 commit comments

Comments
 (0)