Skip to content

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

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?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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