# OpenEnv Container Provider Configuration: LocalDockerProvider vs KubernetesProvider vs UVProvider

> Compare OpenEnv container providers LocalDockerProvider KubernetesProvider and UVProvider for environment execution. Choose the right provider for local development or production deployments.

- Repository: [Hugging Face/OpenEnv](https://github.com/huggingface/OpenEnv)
- Tags: deep-dive
- Published: 2026-06-14

---

**OpenEnv abstracts environment execution through pluggable providers where `LocalDockerProvider` runs containers locally, `KubernetesProvider` (currently a stub) targets production clusters, and `UVProvider` launches ASGI apps directly via `uv run` without Docker overhead.**

OpenEnv from Hugging Face decouples environment lifecycle management from execution strategy through a unified provider interface. Understanding the **OpenEnv container provider configuration** options—spanning from local Docker containers to Kubernetes orchestration and direct Python runtime execution—enables you to optimize for development velocity, isolation requirements, and production scalability.

## Provider Architecture Overview

OpenEnv organizes providers into two distinct families based on execution strategy. The **Container providers** manage Docker-compatible workloads, while **Runtime providers** execute ASGI applications directly.

All providers inherit from abstract base classes (`ContainerProvider` or `RuntimeProvider`) defined in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py). This architecture ensures `EnvClient` remains agnostic to launch mechanisms, requiring only that providers implement lifecycle methods (`start_container`/`stop_container` for containers, `start`/`stop` for runtimes) and `wait_for_ready` health checking.

## LocalDockerProvider: Local Container Isolation

The `LocalDockerProvider` class delivers complete container isolation by spinning up individual Docker containers on your host machine. Located in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py) (lines 101–128), this provider handles the full lifecycle from port allocation to health verification.

### Implementation Details

When you invoke `start_container(image, port=None, env_vars=None, **kwargs)`, the provider first validates Docker installation, selects an available host port (or respects your specified one), and constructs a `docker run … -p <port>:8000` command. It returns a base URL at `http://localhost:<port>` after the container starts.

The `stop_container()` method handles graceful cleanup, while `wait_for_ready(base_url, timeout_s=30.0)` polls the `/health` endpoint until receiving an HTTP 200 response. This polling mechanism ensures your environment is fully initialized before `EnvClient` attempts connections.

### Configuration Example

```python
from openenv.core.containers.runtime import LocalDockerProvider

# Initialize and launch

provider = LocalDockerProvider()
base_url = provider.start_container("echo-env:latest")  # → http://localhost:12345

provider.wait_for_ready(base_url)

# Interact with the environment via base_url

# ...

# Cleanup

provider.stop_container()

```

## KubernetesProvider: Production Cluster Deployment

The `KubernetesProvider` class targets production-grade Kubernetes clusters but currently exists as a stub implementation in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py) (lines 628–634).

### Current Implementation Status

The class definition currently contains only `pass` statements, indicating active development. When fully implemented, it will follow the `ContainerProvider` abstract API: creating Pods or Deployments in user-specified namespaces, exposing them via Services or port-forwarding, and returning reachable base URLs identical to the Docker provider interface.

### Future Architecture

The design mirrors other container providers, intending to leverage native cluster scheduling, networking policies, and resource quotas. You can expect `start_container` to accept additional parameters for namespace configuration, replica counts, and resource limits when the implementation completes.

## UVProvider: Direct Runtime Execution

The `UVProvider` differs fundamentally from container providers—it belongs to the **Runtime provider** family that executes ASGI applications directly via `uv run` without Docker overhead. Implemented in [`src/openenv/core/containers/runtime/uv_provider.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/uv_provider.py) (lines 81–235), this provider optimizes for rapid iteration and CI environments where Docker is unavailable.

### How It Works

The provider validates that the `uv` executable is present (`_check_uv_installed`), finds a free TCP port (`_find_free_port`), and constructs a command: `uv run --project <path> -- uvicorn <app> …` (`_create_uv_command`). It launches this as a subprocess, stores the base URL at `http://127.0.0.1:<port>`, and polls the `/health` endpoint via `_poll_health` until the server reports ready.

### Configuration Example

```python
from openenv.core.containers.runtime import UVProvider

provider = UVProvider(
    project_path="/path/to/echo_env",
    app="server.app:app",
    reload=True,
)
base_url = provider.start()  # → http://127.0.0.1:8000

provider.wait_for_ready()

# Use the environment

# ...

provider.stop()

```

## Choosing the Right Provider

Select your **OpenEnv container provider configuration** based on deployment context and isolation requirements:

- **LocalDockerProvider**: Use when you need Docker isolation on your development machine, require production-image parity, or depend on container-specific tooling. Ideal for local laptop development with Docker Desktop installed.

- **DockerSwarmProvider**: Deploy when testing multi-instance scaling locally. This provider (implementation in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py), lines 310–374) creates Swarm services with configurable replicas and load balancing.

- **KubernetesProvider**: Reserve for managed Kubernetes clusters (GKE, EKS, AKS) once implementation completes. This will provide native cluster scheduling and enterprise networking.

- **UVProvider**: Choose for CI pipelines lacking Docker, rapid prototyping without container overhead, or when working directly with Python source trees. This skips image building entirely.

## Integration with EnvClient

The `EnvClient` class abstracts provider differences, allowing seamless switching between container and runtime execution:

```python
from openenv.core.env_client import EnvClient
from openenv.core.containers.runtime import LocalDockerProvider, UVProvider

# Container-based execution

docker_client = EnvClient(provider=LocalDockerProvider())
docker_client.start("echo-env:latest")

# Runtime-based execution

uv_client = EnvClient(provider=UVProvider(project_path="envs/echo_env"))
uv_client.start()

```

`EnvClient` automatically selects the appropriate start method (`start_container` for containers, `start` for runtimes) and exposes the `base_url` attribute regardless of underlying provider type.

## Summary

- **LocalDockerProvider** manages single-container Docker execution via `docker run` commands in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py), providing full isolation with automatic port mapping and health checking.

- **KubernetesProvider** exists as a stub (lines 628–634) targeting production cluster deployment, sharing the `ContainerProvider` interface but awaiting full implementation.

- **UVProvider** eliminates container overhead by launching ASGI apps directly through `uv run` in [`src/openenv/core/containers/runtime/uv_provider.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/uv_provider.py), optimizing for development speed and CI environments.

- All providers implement `wait_for_ready` polling against `/health` endpoints, ensuring reliable startup detection before returning control to `EnvClient`.

## Frequently Asked Questions

### What is the difference between ContainerProvider and RuntimeProvider in OpenEnv?

Container providers manage Docker-compatible workloads requiring image-based execution, while Runtime providers launch Python processes directly via `uv run`. Container providers like `LocalDockerProvider` and `KubernetesProvider` handle `start_container`/`stop_container` methods, whereas Runtime providers like `UVProvider` use `start`/`stop` signatures and execute ASGI applications without containerization.

### When should I use UVProvider instead of LocalDockerProvider?

Use **UVProvider** when you need rapid iteration without Docker image build times, when running in CI environments lacking Docker daemon access, or when debugging Python source code directly. Choose **LocalDockerProvider** when you require process isolation, need to test production Docker images, or depend on container-specific dependencies and networking.

### Is KubernetesProvider ready for production use?

No, `KubernetesProvider` currently exists as a stub implementation (`pass` statements) in [`src/openenv/core/containers/runtime/providers.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/containers/runtime/providers.py) (lines 628–634). The class structure aligns with the `ContainerProvider` interface but requires implementation of pod creation, service exposure, and cluster authentication logic before production deployment.

### How does port configuration work across different providers?

`LocalDockerProvider` automatically selects available host ports or accepts explicit `port` parameters in `start_container()`, mapping them to port 8000 inside the container. `UVProvider` finds free TCP ports via `_find_free_port()` and binds to `127.0.0.1` for local access. Both providers expose the final URL through their respective `start` methods for `EnvClient` consumption.