OpenEnv CLI Commands: Complete Guide to init, push, serve, build, and validate

The OpenEnv CLI provides five essential commands—init, build, push, validate, and serve—that scaffold, containerize, verify, and deploy Gym-like reinforcement learning environments using a declarative infrastructure-as-code workflow.

The OpenEnv framework from Hugging Face enables developers to package reinforcement learning environments as containerized microservices that expose a standard Gym-compatible API. Mastering these OpenEnv CLI commands allows you to manage the complete lifecycle of environment-as-code projects, from initial project generation to remote registry deployment.

CLI Architecture and Core Design

The OpenEnv CLI is built on Typer and follows a strict separation of concerns between client-side orchestration and server-side execution. Located in src/openenv/cli/commands/, each command acts as a thin wrapper around the core library (src/openenv/core/), delegating heavy lifting to specialized providers while preserving the client-server boundary.

The architecture centers on the MCP (Message-Control-Protocol) layer defined in openenv.core.env_server.mcp_types.py. When you execute CLI commands, they interact with the runtime through openenv.core.env_client.EnvClient, which communicates with containerized environments via WebSocket endpoints exposed by openenv.core.env_server.http_server.

Command: init

The init command scaffolds a new OpenEnv project with all necessary configuration files and starter code. Implemented in src/openenv/cli/commands/init.py, this command performs strict validation and template generation.

When you run:

openenv init my_env

The command executes the following operations:

  • Name validation via _validate_env_name() to ensure my_env is a valid snake_case identifier
  • Template rendering that creates my_env/openenv.yaml, pyproject.toml, Dockerfile, and my_env_environment.py
  • Metadata injection using _get_random_hf_space_config() to populate Hugging Face Space attributes (emoji, colour palette) in openenv.yaml

The resulting project structure includes:


my_env/
├── openenv.yaml            # Environment metadata and runtime config

├── pyproject.toml          # Python dependencies

├── my_env_environment.py   # EnvServer implementation stub

└── Dockerfile              # Container definition

Command: build

The build command compiles your environment into a containerized artifact ready for execution or distribution. Found in src/openenv/cli/commands/build.py, it supports multiple runtime backends through the container abstraction layer.

By default, the build process utilizes src/openenv/core/containers/runtime/uv_provider.py to create lightweight images without a full Docker daemon, though standard Docker builds are also supported. The command produces an image tagged openenv-my-env:latest that bundles your environment code with the OpenEnv server entry point (openenv serve).

cd my_env
openenv build

The build system reads openenv.yaml to determine the runtime configuration and ensures the server module is importable within the container context.

Command: push

Once built, the push command handles registry authentication and image distribution. Located in src/openenv/cli/commands/push.py, it wraps Docker CLI operations via subprocess.run to tag and upload your environment to remote registries including Hugging Face Spaces, Docker Hub, or private repositories.

openenv push --registry docker.io --repo youruser/openenv-my-env

This command automatically tags the local image with the target repository URI and handles the push authentication flow. Upon successful completion, it returns the full image URI for use in deployment manifests or client connection strings.

Command: validate

Before building or pushing, the validate command verifies that your environment conforms to the OpenEnv schema and runtime requirements. Implemented in src/openenv/cli/commands/validate.py, it performs static analysis of your project structure.

Running openenv validate executes these checks:

  • Schema validation of openenv.yaml to confirm required fields (name, version, runtime) are present and correctly typed
  • Code verification that my_env_environment.py contains a class named EnvServer inheriting from openenv.core.env_server.base_transforms.BaseEnv
  • Dependency analysis of pyproject.toml to ensure server-side dependencies are correctly declared

This validation catches configuration errors early in the development cycle, preventing failed builds or runtime protocol mismatches.

Command: serve

The serve command currently exists as a placeholder in src/openenv/cli/commands/serve.py for future local development workflows. While the full implementation is pending, the command provides guidance for current local testing strategies.

openenv serve --port 8080 --reload

Currently, this outputs recommended alternatives:

  1. Docker-based local serving: openenv build && docker run -p 8080:8080 openenv-my-env:latest
  2. Uv-based development: uv run --project . server --port 8080

The future implementation will directly launch the WebSocket server via uv run server, enabling rapid local iteration without container overhead by leveraging the same openenv.core.env_server.http_server module used in production containers.

Complete Development Workflow

A typical OpenEnv project lifecycle combines these commands in sequence:


# 1. Scaffold the project

openenv init my_env

# 2. Navigate and implement your environment logic

cd my_env

# Edit my_env_environment.py to implement your Gym-like logic

# 3. Validate configuration before building

openenv validate

# 4. Build the container image

openenv build

# 5. Push to remote registry for distribution

openenv push --registry docker.io --repo youruser/openenv-my-env

Each step leverages the core library's abstractions: init uses the auto-generation helpers in src/openenv/auto/auto_env.py, while build and push interface with the container runtime abstraction layer in src/openenv/core/containers/runtime/.

Summary

  • OpenEnv CLI commands manage the full lifecycle of RL environments through five specialized operations: init, build, validate, push, and serve.
  • The init command in src/openenv/cli/commands/init.py scaffolds projects with validated names, random HF Space metadata, and Docker configurations.
  • Build and push operations in their respective command files handle containerization and registry distribution, supporting both Docker and uv-based runtimes.
  • Validate ensures schema compliance and proper inheritance from BaseEnv before deployment.
  • Serve remains a placeholder pending direct uv-based local server execution, currently directing users to Docker or manual uv workflows.
  • All commands communicate with the underlying EnvClient and MCP protocol layer, maintaining strict separation between CLI orchestration and server-side environment execution.

Frequently Asked Questions

What is the difference between build and push in OpenEnv?

The build command compiles your environment source into a container image using either Docker or the uv provider, creating a local artifact tagged openenv-my-env:latest. The push command then takes this local image, tags it with a remote registry URI, and uploads it to a container registry such as Docker Hub or Hugging Face Spaces. You must build before pushing, as the push command expects the local image to exist.

Why is the serve command not fully implemented yet?

According to the source code in src/openenv/cli/commands/serve.py, the serve command is currently a placeholder indicating future functionality. The OpenEnv team plans to implement direct local serving using uv run server to launch the WebSocket server without Docker overhead. Until then, the command provides documented workarounds using Docker (openenv build && docker run) or direct uv execution (uv run --project . server).

How does OpenEnv validate that my environment is correctly configured?

The validate command in src/openenv/cli/commands/validate.py performs two primary checks: it parses openenv.yaml to verify required metadata fields (name, version, runtime) are present, and it inspects your generated server module to confirm it contains an EnvServer class that properly inherits from openenv.core.env_server.base_transforms.BaseEnv. This ensures compatibility with the MCP protocol and client-side EnvClient expectations.

What container runtimes does OpenEnv support?

OpenEnv supports an extensible runtime architecture defined in src/openenv/core/containers/runtime/. Currently, it includes a Docker runtime for standard container builds and a uv provider (uv_provider.py) for lightweight, Python-native containerization without a full Docker daemon. Additional runtimes such as Kubernetes or Daytona can be integrated by implementing the abstract base class in the runtime module.

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 →