# How to Configure OpenEnv Container Providers: LocalDockerProvider, UVProvider, and KubernetesProvider

> Learn to configure OpenEnv container providers including LocalDockerProvider, UVProvider, and KubernetesProvider for local development, in-process execution, or cloud deployments.

- Repository: [Hugging Face/OpenEnv](https://github.com/huggingface/OpenEnv)
- Tags: how-to-guide
- Published: 2026-06-15

---

**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`](https://github.com/huggingface/OpenEnv/blob/main/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 URL
- `stop_container()`: Terminates the running instance and cleans up resources  
- `wait_for_ready(base_url, timeout_s=30.0)`: Polls the `/health` endpoint until HTTP 200 or raises `TimeoutError`

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`](https://github.com/huggingface/OpenEnv/blob/main/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:

1. Generates a unique container name to avoid collisions
2. Selects a free host port (or uses the supplied `port` argument)
3. Executes `docker run -d` with the specified image and environment variables
4. 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

```python
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`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/uv_provider.py).

### Key Behaviors

Unlike Docker-based providers, `UVProvider`:

- Starts the environment server in-process without containerization
- Leverages `uvloop` for low-latency async request handling
- Binds to `http://127.0.0.1:<port>` immediately
- Returns instantly from `wait_for_ready` since the server runs synchronously in the same process

This provider eliminates Docker daemon overhead, making it ideal for high-throughput local experiments.

### Usage Example

```python
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`](https://github.com/huggingface/OpenEnv/blob/main/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`:

1. Generates a unique pod name and temporary manifest
2. Creates a Pod resource and a NodePort Service
3. Retrieves the node's external IP and assigned NodePort
4. 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

```python
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

- **`ContainerProvider`** is the abstract interface in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py) that standardizes container lifecycle management across backends.
- **`LocalDockerProvider`** runs Docker containers locally, automatically managing ports and container names while exposing `http://localhost` endpoints.
- **`UVProvider`** executes environments in-process via [`src/openenv/core/containers/runtime/uv_provider.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/uv_provider.py), eliminating container overhead using `uvloop`.
- **`KubernetesProvider`** deploys to clusters using Pod and NodePort resources, requiring `kubectl` access and returning node-external URLs.
- All providers implement `start_container`, `stop_container`, and `wait_for_ready`, enabling seamless switching by passing the provider instance to `EnvClient`.

## 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`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py). The `UVProvider` implementation is located separately in [`src/openenv/core/containers/runtime/uv_provider.py`](https://github.com/huggingface/OpenEnv/blob/main/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`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/env_client.py).