How to Configure OpenEnv Container Providers: LocalDockerProvider, UVProvider, and KubernetesProvider
OpenEnv uses a pluggable ContainerProvider architecture that lets you run environment servers on LocalDockerProvider for local development, UVProvider for in-process execution, or KubernetesProvider for cloud-native deployments, all through a unified interface requiring only start_container, stop_container, and wait_for_ready implementations.
OpenEnv, Hugging Face's open-source environment runtime, abstracts container orchestration through a provider pattern that supports multiple backends. When you configure OpenEnv container providers, you choose how and where your environment servers execute—whether in local Docker containers, directly in the Python process via UV, or distributed across Kubernetes clusters. This guide walks through the three concrete implementations available in the codebase and how to instantiate each with EnvClient.
ContainerProvider Architecture
The foundation of OpenEnv's container abstraction is the abstract base class ContainerProvider defined in src/openenv/core/containers/runtime/providers.py. Any provider must implement three core methods:
start_container(image, port=None, env_vars=None, **kwargs): Launches the container or runtime and returns a base URLstop_container(): Terminates the running instance and cleans up resourceswait_for_ready(base_url, timeout_s=30.0): Polls the/healthendpoint until HTTP 200 or raisesTimeoutError
This interface allows EnvClient to treat Docker, UV, and Kubernetes deployments identically, switching backends by passing a different provider instance.
LocalDockerProvider
LocalDockerProvider is the default provider when none is specified. Located in src/openenv/core/containers/runtime/providers.py, it manages single Docker containers on your development machine.
Key Behaviors
On instantiation, the provider validates that Docker is installed and accessible. When start_container is called, it:
- Generates a unique container name to avoid collisions
- Selects a free host port (or uses the supplied
portargument) - Executes
docker run -dwith the specified image and environment variables - Returns
http://localhost:<port>as the service endpoint
The wait_for_ready implementation polls <base_url>/health until the service responds or the timeout expires.
Usage Example
from openenv.core.env_client import EnvClient
# Defaults to LocalDockerProvider
client = EnvClient(image="echo-env:latest")
print(client.base_url) # http://localhost:8003
client.wait_for_ready()
# ... interact with environment ...
client.close() # Stops and removes container
UVProvider
For scenarios requiring minimal overhead, UVProvider runs the environment server directly in the current Python process using the UV async runtime. Implementation resides in src/openenv/core/containers/runtime/uv_provider.py.
Key Behaviors
Unlike Docker-based providers, UVProvider:
- Starts the environment server in-process without containerization
- Leverages
uvloopfor low-latency async request handling - Binds to
http://127.0.0.1:<port>immediately - Returns instantly from
wait_for_readysince the server runs synchronously in the same process
This provider eliminates Docker daemon overhead, making it ideal for high-throughput local experiments.
Usage Example
from openenv.core.env_client import EnvClient
from openenv.core.containers.runtime import UVProvider
client = EnvClient(
image="echo-env:latest",
provider=UVProvider()
)
print(client.base_url) # http://127.0.0.1:8000
# Server is ready immediately
client.close() # No container cleanup required
KubernetesProvider
For production deployments, KubernetesProvider (also in src/openenv/core/containers/runtime/providers.py) orchestrates pods and services within a Kubernetes cluster.
Key Behaviors
This provider requires a valid kubectl configuration and cluster access. During start_container:
- Generates a unique pod name and temporary manifest
- Creates a Pod resource and a NodePort Service
- Retrieves the node's external IP and assigned NodePort
- Returns
http://<node-ip>:<nodeport>
The wait_for_ready method watches the Kubernetes API for pod status transitions to Ready before polling the /health endpoint.
Usage Example
from openenv.core.env_client import EnvClient
from openenv.core.containers.runtime import KubernetesProvider
provider = KubernetesProvider(namespace="openenv-demo")
client = EnvClient(
image="echo-env:latest",
provider=provider
)
print(client.base_url) # http://34.12.45.67:31568
client.wait_for_ready()
# ... use environment from any cluster-accessible machine ...
client.close() # Deletes pod and service
Provider Selection Guide
Choose your provider based on deployment constraints:
- LocalDockerProvider: Best for standard local development with full container isolation
- UVProvider: Optimal for running many parallel experiments on a single workstation without Docker overhead
- KubernetesProvider: Required for cloud-native production deployments where cluster orchestration is already available
Summary
ContainerProvideris the abstract interface insrc/openenv/core/containers/runtime/providers.pythat standardizes container lifecycle management across backends.LocalDockerProviderruns Docker containers locally, automatically managing ports and container names while exposinghttp://localhostendpoints.UVProviderexecutes environments in-process viasrc/openenv/core/containers/runtime/uv_provider.py, eliminating container overhead usinguvloop.KubernetesProviderdeploys to clusters using Pod and NodePort resources, requiringkubectlaccess and returning node-external URLs.- All providers implement
start_container,stop_container, andwait_for_ready, enabling seamless switching by passing the provider instance toEnvClient.
Frequently Asked Questions
How do I switch between providers in OpenEnv?
Pass the provider instance directly to the EnvClient constructor via the provider parameter. If omitted, EnvClient defaults to LocalDockerProvider. For example, use EnvClient(image="env:latest", provider=UVProvider()) to run in-process, or supply KubernetesProvider(namespace="prod") for cluster deployment.
What are the prerequisites for KubernetesProvider?
You need a valid kubectl configuration with access to a Kubernetes cluster. The provider automatically handles pod creation, service exposure via NodePort, and resource cleanup when close() is called. Ensure your kubeconfig context points to the correct cluster before instantiation.
Can I use UVProvider in production environments?
While UVProvider offers the lowest latency for local experimentation, it lacks the isolation guarantees of containerization. For production workloads, KubernetesProvider or LocalDockerProvider provide better resource boundaries, security isolation, and scalability across nodes.
Where is the ContainerProvider interface defined?
The abstract class ContainerProvider and the concrete implementations for Docker and Kubernetes reside in src/openenv/core/containers/runtime/providers.py. The UVProvider implementation is located separately in src/openenv/core/containers/runtime/uv_provider.py, while the high-level client that consumes these providers is implemented in src/openenv/core/env_client.py.
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 →