Skip to content
Open
Show file tree
Hide file tree
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
8 changes: 6 additions & 2 deletions cmd/cli/commands/install-runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func ensureStandaloneRunnerAvailable(ctx context.Context, printer standalone.Sta
port = standalone.DefaultControllerPortCloud
environment = "cloud"
}
if err := standalone.CreateControllerContainer(ctx, dockerClient, port, host, environment, false, gpu, "", modelStorageVolume, printer, engineKind, debug, false); err != nil {
if err := standalone.CreateControllerContainer(ctx, dockerClient, port, host, environment, false, gpu, "", modelStorageVolume, printer, engineKind, debug, false, ""); err != nil {
return nil, fmt.Errorf("unable to initialize standalone model runner container: %w", err)
}

Expand Down Expand Up @@ -172,6 +172,7 @@ type runnerOptions struct {
doNotTrack bool
pullImage bool
pruneContainers bool
proxyCert string
}

// runInstallOrStart is shared logic for install-runner and start-runner commands
Expand Down Expand Up @@ -285,7 +286,7 @@ func runInstallOrStart(cmd *cobra.Command, opts runnerOptions, debug bool) error
return fmt.Errorf("unable to initialize standalone model storage: %w", err)
}
// Create the model runner container.
if err := standalone.CreateControllerContainer(cmd.Context(), dockerClient, port, opts.host, environment, opts.doNotTrack, gpu, opts.backend, modelStorageVolume, asPrinter(cmd), engineKind, debug, vllmOnWSL); err != nil {
if err := standalone.CreateControllerContainer(cmd.Context(), dockerClient, port, opts.host, environment, opts.doNotTrack, gpu, opts.backend, modelStorageVolume, asPrinter(cmd), engineKind, debug, vllmOnWSL, opts.proxyCert); err != nil {
return fmt.Errorf("unable to initialize standalone model runner container: %w", err)
}

Expand All @@ -300,6 +301,7 @@ func newInstallRunner() *cobra.Command {
var backend string
var doNotTrack bool
var debug bool
var proxyCert string
c := &cobra.Command{
Use: "install-runner",
Short: "Install Docker Model Runner (Docker Engine only)",
Expand All @@ -312,6 +314,7 @@ func newInstallRunner() *cobra.Command {
doNotTrack: doNotTrack,
pullImage: true,
pruneContainers: false,
proxyCert: proxyCert,
}, debug)
},
ValidArgsFunction: completion.NoComplete,
Expand All @@ -323,6 +326,7 @@ func newInstallRunner() *cobra.Command {
Backend: &backend,
DoNotTrack: &doNotTrack,
Debug: &debug,
ProxyCert: &proxyCert,
})
return c
}
3 changes: 3 additions & 0 deletions cmd/cli/commands/reinstall-runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func newReinstallRunner() *cobra.Command {
var backend string
var doNotTrack bool
var debug bool
var proxyCert string
c := &cobra.Command{
Use: "reinstall-runner",
Short: "Reinstall Docker Model Runner (Docker Engine only)",
Expand All @@ -24,6 +25,7 @@ func newReinstallRunner() *cobra.Command {
doNotTrack: doNotTrack,
pullImage: true,
pruneContainers: true,
proxyCert: proxyCert,
}, debug)
},
ValidArgsFunction: completion.NoComplete,
Expand All @@ -35,6 +37,7 @@ func newReinstallRunner() *cobra.Command {
Backend: &backend,
DoNotTrack: &doNotTrack,
Debug: &debug,
ProxyCert: &proxyCert,
})
return c
}
3 changes: 3 additions & 0 deletions cmd/cli/commands/restart-runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func newRestartRunner() *cobra.Command {
var gpuMode string
var doNotTrack bool
var debug bool
var proxyCert string
c := &cobra.Command{
Use: "restart-runner",
Short: "Restart Docker Model Runner (Docker Engine only)",
Expand All @@ -30,6 +31,7 @@ func newRestartRunner() *cobra.Command {
gpuMode: gpuMode,
doNotTrack: doNotTrack,
pullImage: false,
proxyCert: proxyCert,
}, debug)
},
ValidArgsFunction: completion.NoComplete,
Expand All @@ -40,6 +42,7 @@ func newRestartRunner() *cobra.Command {
GpuMode: &gpuMode,
DoNotTrack: &doNotTrack,
Debug: &debug,
ProxyCert: &proxyCert,
})
return c
}
3 changes: 3 additions & 0 deletions cmd/cli/commands/start-runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func newStartRunner() *cobra.Command {
var backend string
var doNotTrack bool
var debug bool
var proxyCert string
c := &cobra.Command{
Use: "start-runner",
Short: "Start Docker Model Runner (Docker Engine only)",
Expand All @@ -21,6 +22,7 @@ func newStartRunner() *cobra.Command {
backend: backend,
doNotTrack: doNotTrack,
pullImage: false,
proxyCert: proxyCert,
}, debug)
},
ValidArgsFunction: completion.NoComplete,
Expand All @@ -31,6 +33,7 @@ func newStartRunner() *cobra.Command {
Backend: &backend,
DoNotTrack: &doNotTrack,
Debug: &debug,
ProxyCert: &proxyCert,
})
return c
}
6 changes: 5 additions & 1 deletion cmd/cli/commands/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,15 @@ func requireMinArgs(n int, cmdName string, usageArgs string) cobra.PositionalArg
}
}

// runnerOptions holds common runner configuration options
// runnerFlagOptions holds common runner configuration options
type runnerFlagOptions struct {
Port *uint16
Host *string
GpuMode *string
Backend *string
DoNotTrack *bool
Debug *bool
ProxyCert *string
}

// addRunnerFlags adds common runner flags to a command
Expand All @@ -213,4 +214,7 @@ func addRunnerFlags(cmd *cobra.Command, opts runnerFlagOptions) {
if opts.Debug != nil {
cmd.Flags().BoolVar(opts.Debug, "debug", false, "Enable debug logging")
}
if opts.ProxyCert != nil {
cmd.Flags().StringVar(opts.ProxyCert, "proxy-cert", "", "Path to a CA certificate file for proxy SSL inspection")
}
}
9 changes: 9 additions & 0 deletions cmd/cli/docs/reference/docker_model_install-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: proxy-cert
value_type: string
description: Path to a CA certificate file for proxy SSL inspection
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
Expand Down
9 changes: 9 additions & 0 deletions cmd/cli/docs/reference/docker_model_reinstall-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: proxy-cert
value_type: string
description: Path to a CA certificate file for proxy SSL inspection
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
Expand Down
9 changes: 9 additions & 0 deletions cmd/cli/docs/reference/docker_model_restart-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: proxy-cert
value_type: string
description: Path to a CA certificate file for proxy SSL inspection
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
Expand Down
9 changes: 9 additions & 0 deletions cmd/cli/docs/reference/docker_model_start-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: proxy-cert
value_type: string
description: Path to a CA certificate file for proxy SSL inspection
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
Expand Down
1 change: 1 addition & 0 deletions cmd/cli/docs/reference/model_install-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Install Docker Model Runner (Docker Engine only)
| `--gpu` | `string` | `auto` | Specify GPU support (none\|auto\|cuda\|rocm\|musa\|cann) |
| `--host` | `string` | `127.0.0.1` | Host address to bind Docker Model Runner |
| `--port` | `uint16` | `0` | Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode) |
| `--proxy-cert` | `string` | | Path to a CA certificate file for proxy SSL inspection |


<!---MARKER_GEN_END-->
Expand Down
1 change: 1 addition & 0 deletions cmd/cli/docs/reference/model_reinstall-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Reinstall Docker Model Runner (Docker Engine only)
| `--gpu` | `string` | `auto` | Specify GPU support (none\|auto\|cuda\|rocm\|musa\|cann) |
| `--host` | `string` | `127.0.0.1` | Host address to bind Docker Model Runner |
| `--port` | `uint16` | `0` | Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode) |
| `--proxy-cert` | `string` | | Path to a CA certificate file for proxy SSL inspection |


<!---MARKER_GEN_END-->
Expand Down
1 change: 1 addition & 0 deletions cmd/cli/docs/reference/model_restart-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Restart Docker Model Runner (Docker Engine only)
| `--gpu` | `string` | `auto` | Specify GPU support (none\|auto\|cuda\|rocm\|musa\|cann) |
| `--host` | `string` | `127.0.0.1` | Host address to bind Docker Model Runner |
| `--port` | `uint16` | `0` | Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode) |
| `--proxy-cert` | `string` | | Path to a CA certificate file for proxy SSL inspection |


<!---MARKER_GEN_END-->
Expand Down
1 change: 1 addition & 0 deletions cmd/cli/docs/reference/model_start-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Start Docker Model Runner (Docker Engine only)
| `--do-not-track` | `bool` | | Do not track models usage in Docker Model Runner |
| `--gpu` | `string` | `auto` | Specify GPU support (none\|auto\|cuda\|rocm\|musa\|cann) |
| `--port` | `uint16` | `0` | Docker container port for Docker Model Runner (default: 12434 for Docker Engine, 12435 for Cloud mode) |
| `--proxy-cert` | `string` | | Path to a CA certificate file for proxy SSL inspection |


<!---MARKER_GEN_END-->
Expand Down
33 changes: 31 additions & 2 deletions cmd/cli/pkg/standalone/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func copyDockerConfigToContainer(ctx context.Context, dockerClient *client.Clien

func execInContainer(ctx context.Context, dockerClient *client.Client, containerID, cmd string) error {
execConfig := container.ExecOptions{
Cmd: []string{"sh", "-c", cmd},
Cmd: []string{"sh", "-c", cmd},
User: "root",
Copy link
Contributor

Choose a reason for hiding this comment

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

🚨 issue (security): Running all execs as root may be unnecessarily privileged and surprising for containers that define a non-root default user.

This change alters behavior for images that deliberately run as non-root and may violate security expectations by always elevating to root. Please consider limiting root usage to the specific privileged operations that need it (e.g., via an asRoot flag or a separate helper), and keep default execs running as the container’s configured user.

}
execResp, err := dockerClient.ContainerExecCreate(ctx, containerID, execConfig)
if err != nil {
Expand Down Expand Up @@ -267,8 +268,12 @@ func tryGetBindAscendMounts(printer StatusPrinter, debug bool) []mount.Mount {
return newMounts
}

// proxyCertContainerPath is the path where the proxy certificate will be mounted in the container.
// This location is used by update-ca-certificates to add the cert to the system trust store.
const proxyCertContainerPath = "/usr/local/share/ca-certificates/proxy-ca.crt"

// 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) error {
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) error {
imageName := controllerImageName(gpu, backend)

// Set up the container configuration.
Expand All @@ -288,6 +293,7 @@ func CreateControllerContainer(ctx context.Context, dockerClient *client.Client,
env = append(env, proxyVar+"="+value)
}
}

config := &container.Config{
Image: imageName,
Env: env,
Expand Down Expand Up @@ -316,6 +322,15 @@ func CreateControllerContainer(ctx context.Context, dockerClient *client.Client,
hostConfig.Mounts = append(hostConfig.Mounts, ascendMounts...)
}

if proxyCert != "" {
hostConfig.Mounts = append(hostConfig.Mounts, mount.Mount{
Type: mount.TypeBind,
Source: proxyCert,
Target: proxyCertContainerPath,
ReadOnly: true,
})
Comment on lines +325 to +331
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (bug_risk): Binding the proxy cert path without validation may produce a non-obvious Docker error if the file is missing or invalid.

If --proxy-cert points to a missing or unreadable file, the container will fail to start due to the bind mount, but the CLI will only show a generic startup error. Consider validating the path (existence/readability) before adding the mount so you can return a clearer, targeted error when the certificate path is invalid.

Suggested implementation:

import (
	"os"
	if proxyCert != "" {
		info, err := os.Stat(proxyCert)
		if err != nil {
			// Fail fast with a clear, targeted error instead of a generic Docker bind error
			return nil, nil, fmt.Errorf("proxy certificate path %q is not accessible: %w", proxyCert, err)
		}
		if !info.Mode().IsRegular() {
			return nil, nil, fmt.Errorf("proxy certificate path %q is not a regular file", proxyCert)
		}

		hostConfig.Mounts = append(hostConfig.Mounts, mount.Mount{
			Type:     mount.TypeBind,
			Source:   proxyCert,
			Target:   proxyCertContainerPath,
			ReadOnly: true,
		})
	}

Because I cannot see the full function, you will need to:

  1. Adjust the return nil, nil, fmt.Errorf(...) lines to match the actual return types of the function where this proxyCert logic lives.
    • For example, if the function returns (config *container.Config, hostConfig *container.HostConfig, err error), the nil, nil, err form is correct; otherwise, replace the nil placeholders appropriately.
  2. Ensure fmt is imported in this file (if it is not already):
    • Add fmt to the import block: import ("fmt" ... ).
  3. If os is already imported, remove the duplicate os line from the suggested import change.
  4. Keep error messages consistent with the rest of the CLI (e.g. wrapping with your own error type or prefixing with command context if that is the existing pattern).

}

portBindings := []nat.PortBinding{{HostIP: host, HostPort: portStr}}
if os.Getenv("_MODEL_RUNNER_TREAT_DESKTOP_AS_MOBY") != "1" {
// Don't bind the bridge gateway IP if we're treating Docker Desktop as Moby.
Expand Down Expand Up @@ -437,6 +452,20 @@ func CreateControllerContainer(ctx context.Context, dockerClient *client.Client,
printer.Printf("Warning: failed to copy Docker config: %v\n", err)
}
}

// Add proxy certificate to the system CA bundle
if created && proxyCert != "" {
printer.Printf("Updating CA certificates...\n")
if err := execInContainer(ctx, dockerClient, resp.ID, "update-ca-certificates"); err != nil {
printer.Printf("Warning: failed to update CA certificates: %v\n", err)
} else {
printer.Printf("Restarting container to apply CA certificate...\n")
if err := dockerClient.ContainerRestart(ctx, resp.ID, container.StopOptions{}); err != nil {
printer.Printf("Warning: failed to restart container after adding CA certificate: %v\n", err)
}
}
}

return nil
}

Expand Down
Loading