Using Container Environment Variables to Configure Runtime Behavior in OpenEnv

OpenEnv reads configuration values from container environment variables at startup using os.getenv, allowing the same environment image to run across local development, Docker, Kubernetes, and remote inference services without code changes.

OpenEnv from Hugging Face builds each environment as a lightweight FastAPI service that configures itself entirely through container environment variables. This design pattern lets you reuse the same Docker image across development, staging, and production simply by changing the variables injected at runtime. Whether you are running a wildfire simulation or an Atari game wrapper, the configuration logic in app.py files like envs/wildfire_env/server/app.py relies on standard os.getenv calls to control grid dimensions, concurrency limits, and feature toggles.

How OpenEnv Reads Container Environment Variables

Reading Variables with Default Values

Each environment’s app.py begins by importing os and calling os.getenv with sensible defaults. This ensures the service starts even when variables are missing.

In envs/wildfire_env/server/app.py, the server reads grid dimensions and concurrency limits:

import os

W = int(os.getenv("WILDFIRE_WIDTH", "16"))
H = int(os.getenv("WILDFIRE_HEIGHT", "16"))
max_concurrent = int(os.getenv("MAX_CONCURRENT_ENVS", "8"))

The retrieved values pass directly to the environment constructor:

return WildfireEnvironment(width=W, height=H)

Boolean Flags and Conditional Features

Boolean toggles use case-insensitive evaluation to enable optional UI components or debug modes. In envs/wildfire_env/server/app.py, the web interface flag parses as follows:

enable_web = os.getenv("ENABLE_WEB_INTERFACE", "false").lower() in ("true", "1", "yes")

This pattern allows strings like "True", "1", or "yes" to activate features consistently across shell scripts and YAML manifests.

Centralized Server Factory

All environments leverage the shared create_app helper in src/openenv/core/env_server/http_server.py. This factory reads global variables like MAX_CONCURRENT_ENVS and ENABLE_WEB_INTERFACE before instantiating the FastAPI application, guaranteeing a consistent HTTP interface regardless of the specific environment logic.

Commonly Used Environment Variables

OpenEnv respects the following variables across different environment types:

  • MAX_CONCURRENT_ENVS: Default 8. Controls the maximum number of parallel environment instances the server hosts.
  • ENABLE_WEB_INTERFACE: Default false. When set to "true", injects custom HTML UI routes (e.g., the wildfire visualization).
  • PORT: Default 8000. TCP port for the uvicorn server binding.
  • WILDFIRE_WIDTH / WILDFIRE_HEIGHT: Default 16. Grid dimensions for the wildfire simulation.
  • ATARI_GAME / ATARI_OBS_TYPE: Default pong and rgb. Selects the ROM and observation encoding for Atari environments.
  • SUMO_NET_FILE / SUMO_ROUTE_FILE: Paths to SUMO simulation files for traffic control scenarios.
  • CARLA_SCENARIO / CARLA_MODE: Default trolley_saves and mock. Configures autonomous driving scenarios.

Every variable follows the same idiom: an os.getenv call with a default, converted to the appropriate Python type (int, float, or bool).

Runtime Configuration Examples

Docker Deployment

Pass variables via the -e flag when running the container:

docker run -p 8000:8000 \
  -e MAX_CONCURRENT_ENVS=16 \
  -e ENABLE_WEB_INTERFACE=true \
  -e WILDFIRE_WIDTH=32 \
  -e WILDFIRE_HEIGHT=32 \
  huggingface/openenv-wildfire:latest

This command launches a 32×32 wildfire grid with the web UI enabled on port 8000.

Kubernetes Pod Configuration

Inject variables through the env block in your pod spec:

apiVersion: v1
kind: Pod
metadata:
  name: echo-env
spec:
  containers:
    - name: echo
      image: huggingface/openenv-echo:latest
      env:
        - name: MAX_CONCURRENT_ENVS
          value: "4"
        - name: ENABLE_WEB_INTERFACE
          value: "false"

Local Python Development

Set variables in your shell or Python script before importing the server:

import os
from envs.echo_env.server.app import main

os.environ["MAX_CONCURRENT_ENVS"] = "2"
os.environ["ENABLE_WEB_INTERFACE"] = "true"

if __name__ == "__main__":
    main()

This local execution respects the same configuration interface as containerized deployments.

Extending the Pattern for Custom Environments

When creating a new environment, add configuration variables at the top of your app.py:

import os

# Custom parameter with default

my_param = os.getenv("MY_PARAM", "default_value")

# Boolean flag

my_flag = os.getenv("MY_FLAG", "false").lower() in ("true", "1", "yes")

Pass these values to your environment constructor. Because create_app in src/openenv/core/env_server/http_server.py already handles MAX_CONCURRENT_ENVS and ENABLE_WEB_INTERFACE, you inherit global capabilities automatically.

Summary

  • OpenEnv uses os.getenv in envs/*/server/app.py files to read container environment variables at startup.
  • Default values ensure the service runs without explicit configuration, while type conversion handles integers, floats, and booleans.
  • The create_app factory in src/openenv/core/env_server/http_server.py centralizes common settings like concurrency limits and web UI toggles.
  • You can configure deployments identically across Docker, Kubernetes, and local Python processes by changing only the injected variables.

Frequently Asked Questions

How does OpenEnv handle missing environment variables?

OpenEnv supplies sensible defaults in every os.getenv call. For example, MAX_CONCURRENT_ENVS defaults to "8" and PORT defaults to "8000", ensuring the FastAPI server starts even if you provide no variables.

Can I add my own custom environment variables to a new environment?

Yes. Add an os.getenv("MY_VAR", "default") line at the top of your environment's app.py, then pass the value to your constructor. The centralized server factory automatically respects standard variables like MAX_CONCURRENT_ENVS without additional code.

What is the correct format for boolean environment variables in OpenEnv?

OpenEnv checks for case-insensitive truthy values. Set the variable to "true", "1", or "yes" to enable a feature. Any other value, including "false" or an empty string, evaluates to disabled.

Where is the server port configured in OpenEnv?

The PORT variable is read in individual app.py files (e.g., envs/wildfire_env/server/app.py) using int(os.getenv("PORT", "8000")), then passed to the uvicorn server in the main() function.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →