Skip to content

Docker image ENV vars are not propagated to runtime sandbox processes #2268

@uucloud

Description

@uucloud

Summary

When building a template from a Docker image that defines ENV variables (e.g. ENV PYTHONPATH=/app), those variables are correctly used during template build (RUN commands), but are not available to processes started at runtime via the Process.Start RPC.

Analysis

I traced the environment variable flow through the codebase and found:

Build time — works correctly

Docker image ENV vars are parsed from the OCI config into metadata.Context.EnvVars, and each RUN command explicitly passes them via ProcessConfig.Envs:

// packages/orchestrator/pkg/template/build/sandboxtools/command.go
envs := maps.Clone(metadata.EnvVars)
runCmdReq := connect.NewRequest(&process.StartRequest{
    Process: &process.ProcessConfig{
        Cmd:  "/bin/bash",
        Args: []string{"-l", "-c", command},
        Envs: envs,
    },
})

Runtime — ENV vars are lost

When a sandbox is created at runtime, the orchestrator sends env vars to envd via POST /init:

// packages/orchestrator/pkg/sandbox/envd.go
jsonBody := &envd.PostInitJSONBody{
    EnvVars: s.Config.Envd.Vars,  // ← only user-provided env vars from SDK
    ...
}

s.Config.Envd.Vars comes from the gRPC SandboxConfig.EnvVars, which originates from the API's body.EnvVars — these are user-provided env vars only. The template metadata's context.env_vars (containing Docker image ENV) does not appear to be merged into this path.

Inside envd, child process environment is built explicitly in handler.New:

// packages/envd/internal/services/process/handler/handler.go
formattedVars = append(formattedVars, "PATH="+os.Getenv("PATH"))
formattedVars = append(formattedVars, "HOME="+user.HomeDir)
// ... defaults.EnvVars (from MMDS + /init) ...
// ... per-request envs ...
cmd.Env = formattedVars

Only PATH is taken from os.Getenv(). Other Docker image ENV vars are not in defaults.EnvVars and are therefore absent from child processes.

Also, envd does not read /etc/environment or any filesystem-based env config at startup.

Concrete example

FROM python:3.11
ENV MY_APP_CONFIG=/etc/myapp/config.json
ENV PYTHONPATH=/app/lib

After building a template from this image:

  • RUN echo $MY_APP_CONFIG during build → works ✓
  • sdk.process.start("echo $MY_APP_CONFIG") at runtime → empty ✗

Question

  1. Is this the intended behavior? If so, what is the design rationale for not propagating Docker image ENV to runtime processes?

  2. Is there a recommended workaround? Should users manually pass all Docker image ENV vars via the SDK's envVars parameter when creating a sandbox?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions