The Docker-based Open edX distribution designed for peace of mind
Complete command-line interface for Open edX deployment and management. Tutor provides a comprehensive CLI that supports local development, production deployment, configuration management, plugin administration, and Docker image building.
The primary CLI entry point that dynamically loads commands including plugin-provided commands.
def main() -> None:
"""
Main CLI entry point. Initializes hooks system and handles global exceptions.
"""
class TutorCli(click.Group):
"""
Dynamically load subcommands at runtime including plugin commands.
"""
def get_command(self, ctx: click.Context, cmd_name: str) -> Optional[click.Command]: ...
def list_commands(self, ctx: click.Context) -> list[str]: ...
@click.group(cls=TutorCli)
@click.version_option()
@click.option("-r", "--root", envvar="TUTOR_ROOT", type=click.Path(resolve_path=True))
@click.option("-h", "--help", "show_help", is_flag=True)
def cli(context: click.Context, root: str, show_help: bool) -> None:
"""
Main CLI group command with global options for project root and help.
"""Manage Open edX platform configuration including interactive setup, value printing, and patch management.
@click.group(name="config")
def config_command(): ...
@click.command()
@click.option("--interactive", "-i", is_flag=True)
@click.option("--set", "set_vars", multiple=True, type=ConfigKeyValParamType())
@click.option("--append", "append_vars", multiple=True, type=ConfigListKeyValParamType())
@click.option("--remove", "remove_vars", multiple=True, type=ConfigListKeyValParamType())
@click.option("--unset", "unset_vars", multiple=True)
@click.option("--env-only", is_flag=True)
@click.option("--clean-env", is_flag=True)
def save(context: Context, interactive: bool, set_vars: list[tuple[str, Any]],
append_vars: list[tuple[str, Any]], remove_vars: list[tuple[str, Any]],
unset_vars: list[str], env_only: bool, clean_env: bool) -> None:
"""
Create and save configuration interactively or with specified values.
"""
@click.command()
def printroot(context: Context) -> None:
"""
Print the project root directory.
"""
@click.command()
@click.argument("key")
def printvalue(context: Context, key: str) -> None:
"""
Print a specific configuration value.
"""
@click.command()
def edit(context: Context) -> None:
"""
Edit config.yml in the default text editor.
"""
@click.group()
def patches(): ...
@click.command(name="list")
def patches_list(context: Context) -> None:
"""
Print available template patches.
"""
@click.command()
@click.argument("name")
def patches_show(context: Context, name: str) -> None:
"""
Print the rendered contents of a specific patch.
"""Run Open edX locally with Docker Compose for development and testing.
@click.group()
def local(): ...
@click.command()
@click.option("--non-interactive", is_flag=True)
@click.option("--pullimages", is_flag=True)
@click.option("--skip-build", is_flag=True)
def launch(context: Context, non_interactive: bool, pullimages: bool, skip_build: bool) -> None:
"""
Configure and run Open edX from scratch in local mode.
"""
@click.command()
def start(context: Context) -> None:
"""
Start Open edX platform services.
"""
@click.command()
def stop(context: Context) -> None:
"""
Stop Open edX platform services.
"""
@click.command()
def restart(context: Context) -> None:
"""
Restart Open edX platform services.
"""
@click.command()
def status(context: Context) -> None:
"""
Display status of all services.
"""
@click.command()
@click.argument("services", nargs=-1)
def logs(context: Context, services: tuple[str, ...]) -> None:
"""
View logs from services.
"""Run Open edX with development settings for rapid iteration and debugging.
@click.group()
def dev(): ...
@click.command()
def hosts(context: Context) -> None:
"""
List status of all services with their URLs.
"""
# All local commands are also available in dev mode
# (launch, start, stop, restart, status, logs, etc.)Deploy and manage Open edX on Kubernetes with kubectl integration.
@click.group()
def k8s(): ...
@click.command()
@click.option("--non-interactive", is_flag=True)
@click.option("--pullimages", is_flag=True)
@click.option("--skip-build", is_flag=True)
def launch(context: Context, non_interactive: bool, pullimages: bool, skip_build: bool) -> None:
"""
Configure and run Open edX from scratch on Kubernetes.
"""
@click.command()
def start(context: Context) -> None:
"""
Start Open edX platform on Kubernetes.
"""
@click.command()
def stop(context: Context) -> None:
"""
Stop Open edX platform on Kubernetes.
"""
@click.command()
@click.argument("services", nargs=-1)
def logs(context: Context, services: tuple[str, ...]) -> None:
"""
View logs from Kubernetes pods.
"""
@click.command()
@click.argument("service")
@click.argument("command", nargs=-1)
def exec(context: Context, service: str, command: tuple[str, ...]) -> None:
"""
Execute command in a Kubernetes pod.
"""Install, enable, disable, and manage Tutor plugins including discovery and configuration.
@click.group()
def plugins_command(): ...
@click.command(name="list")
def list_plugins(context: Context) -> None:
"""
List installed plugins with their status.
"""
@click.command()
@click.argument("plugin_names", nargs=-1, type=PluginName())
def enable(context: Context, plugin_names: tuple[str, ...]) -> None:
"""
Enable one or more plugins.
"""
@click.command()
@click.argument("plugin_names", nargs=-1, type=PluginName())
def disable(context: Context, plugin_names: tuple[str, ...]) -> None:
"""
Disable one or more plugins.
"""
@click.command()
@click.argument("plugin_names", nargs=-1, type=IndexPluginName())
def install(context: Context, plugin_names: tuple[str, ...]) -> None:
"""
Install plugins from plugin indexes or Git repositories.
"""
@click.command()
@click.argument("plugin_names", nargs=-1, type=PluginName())
def uninstall(context: Context, plugin_names: tuple[str, ...]) -> None:
"""
Uninstall plugins.
"""Build, pull, and push Docker images for Open edX services and plugins.
@click.group()
def images_command(): ...
@click.command()
@click.argument("image_names", nargs=-1)
@click.option("--target", multiple=True)
@click.option("--build-arg", multiple=True)
@click.option("--add-host", multiple=True)
@click.option("--build-context", multiple=True)
def build(context: Context, image_names: tuple[str, ...], target: tuple[str, ...],
build_arg: tuple[str, ...], add_host: tuple[str, ...],
build_context: tuple[str, ...]) -> None:
"""
Build Docker images for specified services.
"""
@click.command()
@click.argument("image_names", nargs=-1)
def pull(context: Context, image_names: tuple[str, ...]) -> None:
"""
Pull Docker images for specified services.
"""
@click.command()
@click.argument("image_names", nargs=-1)
def push(context: Context, image_names: tuple[str, ...]) -> None:
"""
Push Docker images for specified services.
"""Manage bind mounts for development workflows.
@click.group()
def mounts_command(): ...
@click.command(name="list")
def list_mounts(context: Context) -> None:
"""
List current bind mount configuration.
"""
@click.command()
@click.argument("service")
@click.argument("host_path")
@click.argument("container_path")
def add(context: Context, service: str, host_path: str, container_path: str) -> None:
"""
Add a bind mount for a service.
"""
@click.command()
@click.argument("service")
@click.argument("container_path")
def remove(context: Context, service: str, container_path: str) -> None:
"""
Remove a bind mount for a service.
"""class PluginName(click.ParamType):
"""
Click parameter type for plugin names with auto-completion.
"""
def convert(self, value: str, param: Optional[click.Parameter], ctx: Optional[click.Context]) -> str: ...
class IndexPluginName(click.ParamType):
"""
Click parameter type for plugin names from indexes with auto-completion.
"""
def convert(self, value: str, param: Optional[click.Parameter], ctx: Optional[click.Context]) -> str: ...
class ConfigKeyValParamType(click.ParamType):
"""
Parser for <KEY>=<YAML VALUE> command line arguments.
"""
def convert(self, value: str, param: Any, ctx: Any) -> tuple[str, Any]: ...
class ConfigListKeyValParamType(ConfigKeyValParamType):
"""
Same as ConfigKeyValParamType but for keys of type list.
"""
pass# Initialize configuration interactively
tutor config save --interactive
# Launch locally
tutor local launch
# Check status
tutor local status
# View logs
tutor local logs lms cms# List available plugins
tutor plugins list
# Install and enable a plugin
tutor plugins install discovery
tutor plugins enable discovery
# Rebuild configuration with plugin
tutor config save# Configure for Kubernetes
tutor config save --set K8S_NAMESPACE=openedx
# Deploy to Kubernetes
tutor k8s launch
# Check pod status
tutor k8s statusInstall with Tessl CLI
npx tessl i tessl/pypi-tutor