Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cmd/cli/pkg/standalone/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,17 @@ type TLSOptions struct {
// tlsCertContainerPath is the path where TLS certificates will be mounted in the container.
const tlsCertContainerPath = "/etc/model-runner/certs"

// isPortBindingError checks if the error indicates a port is already in use
func isPortBindingError(err error) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it'd be nice to actually check whether it's another DMR instance running on that port, perhaps by checking http://localhost:12434/engines/status.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@doringeman Actually that would require to do this extra http request every single time. Because it does only affect to DD users that install vllm on WSL I prefer to not add the additional check and just add the hint in the error message.

if err == nil {
return false
}
errStr := err.Error()
return strings.Contains(errStr, "ports are not available") &&
(strings.Contains(errStr, "address already in use") ||
strings.Contains(errStr, "Only one usage of each socket address"))
Copy link
Contributor

Choose a reason for hiding this comment

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

How do you get this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can force it by using install-runner when DD has TCP enabled (its the same that @krissetto got: #526)

}
Comment on lines +293 to +301
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To improve readability and maintainability, it's a good practice to extract magic strings into named constants. This makes the code easier to understand and modify in the future.

func isPortBindingError(err error) bool {
	if err == nil {
		return false
	}
	const (
		portBindingErrorStr        = "ports are not available"
		addressInUseErrorStr       = "address already in use"
		socketAddressUsageErrorStr = "Only one usage of each socket address"
	)
	errStr := err.Error()
	return strings.Contains(errStr, portBindingErrorStr) &&
		(strings.Contains(errStr, addressInUseErrorStr) ||
			strings.Contains(errStr, socketAddressUsageErrorStr))
}


// CreateControllerContainer creates and starts a controller container.
func CreateControllerContainer(ctx context.Context, dockerClient *client.Client, port uint16, host string, environment string, doNotTrack bool, gpu gpupkg.GPUSupport, backend string, modelStorageVolume string, printer StatusPrinter, engineKind types.ModelRunnerEngineKind, debug bool, vllmOnWSL bool, proxyCert string, tlsOpts TLSOptions) error {
imageName := controllerImageName(gpu, backend)
Expand Down Expand Up @@ -554,6 +565,9 @@ func CreateControllerContainer(ctx context.Context, dockerClient *client.Client,
if created {
_ = dockerClient.ContainerRemove(ctx, resp.ID, container.RemoveOptions{Force: true})
}
if isPortBindingError(err) {
return fmt.Errorf("failed to start container %s: %w\n\nThe port may already be in use by Docker Desktop's Model Runner.\nTry running: docker desktop disable model-runner", controllerContainerName, err)
}
return fmt.Errorf("failed to start container %s: %w", controllerContainerName, err)
}

Expand Down
Loading