e2b-dev / e2b-dev/runtime

Docker image ENV vars are not propagated to runtime sandbox processes

Open
#2,268 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Build System improvement
Dominant language
Go
Stars
1.6k
Forks
438
PR merge metrics
No merged PRs in 30d

Description

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?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/orchestrator/pkg/sandbox/envd.go and packages/envd/internal/services/process/handler/handler.go, then trace SandboxConfig.EnvVars and template metadata.Context.EnvVars through the runtime path. Compare the build-time ProcessConfig.Envs handling with POST /init and determine the intended behavior, including a supported workaround or a clearly scoped propagation change.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go
Domain
backend, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.