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: Default8. Controls the maximum number of parallel environment instances the server hosts.ENABLE_WEB_INTERFACE: Defaultfalse. When set to"true", injects custom HTML UI routes (e.g., the wildfire visualization).PORT: Default8000. TCP port for the uvicorn server binding.WILDFIRE_WIDTH/WILDFIRE_HEIGHT: Default16. Grid dimensions for the wildfire simulation.ATARI_GAME/ATARI_OBS_TYPE: Defaultpongandrgb. 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: Defaulttrolley_savesandmock. 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.getenvinenvs/*/server/app.pyfiles 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_appfactory insrc/openenv/core/env_server/http_server.pycentralizes 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →