OpenEnv Container Provider Configuration: LocalDockerProvider vs KubernetesProvider vs UVProvider

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. 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 (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

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 (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 (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

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, 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:

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, 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, 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 (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.

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 →