How to Deploy Environments to Hugging Face Spaces Using the openenv CLI push Command

The openenv push command transforms a local OpenEnv environment into a hosted Hugging Face Space by validating the environment structure, authenticating with Hugging Face, staging files, and uploading them to a Space repository.

The openenv CLI provides a streamlined workflow for deploying interactive environments to Hugging Face Spaces. By using the push command, you can turn a local directory containing an openenv.yaml manifest and Dockerfile into a fully hosted Space. This guide explains exactly how the deployment process works according to the huggingface/OpenEnv source code.

How the openenv push Command Works

When you execute openenv push, the CLI follows a precise 10-step pipeline defined in src/openenv/cli/commands/push.py. Understanding these steps helps you troubleshoot deployment issues and optimize your configuration.

1. Environment Validation

The command first verifies that your directory contains the required OpenEnv structure. It calls validate_env_structure from src/openenv/cli/_cli_utils.py (lines 18‑31) to ensure the presence of openenv.yaml, README.md, and a valid Dockerfile. If any required files are missing, the CLI exits with a descriptive error before attempting network operations.

2. Manifest Parsing

The CLI reads openenv.yaml to extract the environment name and configuration (lines 38‑42 of push.py). This manifest drives subsequent decisions about repository naming and default variables.

3. Hugging Face Authentication

If you are not already logged in, the CLI invokes whoami and falls back to login to acquire a valid HF token (lines 46‑78). This ensures all subsequent API calls are authenticated without requiring manual token management.

4. Repository ID Resolution

When you omit the --repo-id argument, the CLI constructs a default identifier using the pattern username/env-name, combining your Hugging Face username with the environment name from the manifest (lines 20‑24). You can override this by providing an explicit --repo-id such as my-org/my-game.

5. Ignore Pattern Loading

To prevent uploading unnecessary files, the CLI loads default ignore patterns (.git*, __pycache__, *.pyc) and merges them with any custom .gitignore-style file via _load_ignore_patterns (lines 151‑188). These patterns filter the files sent to the Space.

6. Staging Directory Preparation

The CLI creates a temporary staging directory where it prepares the final upload payload. During this phase, _prepare_staging_directory (lines 211‑258) optionally rewrites the Dockerfile to set a custom base image or enable the web interface, and patches README.md with the Space front-matter (base_path: /web) required for the Hugging Face UI.

7. Space Creation

If the target Space does not exist, _create_hf_space (lines 262‑281) calls HfApi.create_repo with repo_type="space" and applies your --private and --hardware flags (such as t4-medium or cpu-basic).

8. File Upload

The CLI uploads the staged directory using api.upload_folder (lines 292‑319), respecting the ignore patterns compiled earlier. If you pass --create-pr, the upload opens a Pull Request instead of committing directly to the main branch.

9. Variables and Secrets Configuration

Public variables (--env-var) and private secrets (--secret) are injected into the Space using api.add_space_variable and api.add_space_secret (lines 70‑84). Secret values are masked in logs to prevent accidental exposure.

10. URL Reporting

Finally, the CLI prints the URL of your newly created Space (lines 322‑328), allowing you to immediately access the deployed environment.

Deployment Examples

The following examples demonstrate common deployment patterns using the openenv CLI.

Deploy the Current Directory

Run this from within your OpenEnv folder to deploy with default settings (web UI enabled automatically):

cd my_openenv
openenv push

Deploy to a Private Space with GPU

Specify the repository, privacy setting, and hardware accelerator:

openenv push --repo-id my-org/my-game \
             --private \
             --hardware t4-medium

Use a Custom Base Image

Override the Dockerfile base image during the staging phase:

openenv push --base-image ghcr.io/huggingface/openenv-base:latest

Deploy Multiple Instances

Create multiple Spaces at once for A/B testing or load distribution:

openenv push --count 3

Inject Variables and Secrets

Pass public configuration variables and sensitive API keys (values are not logged):

openenv push -e MAX_STEPS=200 -e GAME=chess \
             --secret OPENAI_API_KEY=sk-********

Deploy to an External Docker Registry

Instead of creating a Hugging Face Space, build and push directly to a container registry:

openenv push --registry docker.io/myuser \
             --no-interface

Advanced Configuration Options

When using --registry, the CLI bypasses Space creation and executes the build logic from src/openenv/cli/commands/build.py, calling _build_docker_image and _push_docker_image to handle the container lifecycle directly. This is useful for integrating OpenEnv environments into existing Kubernetes workflows or third-party hosting platforms.

The --count flag triggers parallel deployments, generating sequentially named repositories (e.g., my-env-1, my-env-2) when a default repo ID is used. Each instance receives the same environment variables and secrets, but runs independently.

Summary

  • openenv push validates your environment via validate_env_structure before any network operations.
  • The CLI stages files in a temporary directory, rewriting the Dockerfile and README to enable the web interface at base_path: /web.
  • Authentication is handled automatically via whoami and login helpers.
  • You can deploy to Hugging Face Spaces with custom hardware, privacy settings, and secrets using flags like --hardware, --private, and --secret.
  • For container-only workflows, use --registry to push to external Docker registries instead of creating Spaces.

Frequently Asked Questions

What files must be present before running openenv push?

The command requires openenv.yaml (the manifest), README.md, and a Dockerfile at the repository root or in a server/ subdirectory. The validate_env_structure function in src/openenv/cli/_cli_utils.py enforces these requirements and will exit with an error if any are missing.

How do I deploy to a private Space with specific hardware?

Use the --private flag combined with --hardware followed by the desired hardware identifier (e.g., t4-medium, cpu-basic). The CLI passes these parameters to HfApi.create_repo in the _create_hf_space function.

Can I deploy to an external Docker registry instead of Hugging Face Spaces?

Yes. Specify --registry followed by the registry URL (e.g., docker.io/myuser). When this flag is present, the CLI invokes the build utilities from src/openenv/cli/commands/build.py to construct and push the image directly, bypassing Space creation and the Hugging Face upload logic.

How does the CLI handle sensitive environment variables?

Variables passed via --secret are set using api.add_space_secret, which stores them as encrypted secrets in the Space. These values never appear in CLI logs or the openenv.yaml file, ensuring they remain secure according to the implementation in lines 70‑84 of push.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:

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 →