Hi all,
I’d like to present you one of the projects I’ve been working on for several months. It is still in development but slowly reach a usable point.
Its name is ox-orch, you can check it here: GitHub - oxylus-tech/ox-orch: A state-driven orchestration engine for deterministic application lifecycle management. · GitHub (documentation: ox-orch - Read the Docs Community)
So what’s ox-orch? It is a state-driven orchestration engine for deterministic application lifecycle management. In a nutshell, it provides a structured way to define, execute and rollback complex workflows such as package installation, migration, and application reconciliation making its best effort to keep deployment state coherent and clean.
This project provides:
- A library that allows you to integrate it into your own projects;
- A command line tool using configuration files to run workflows and manage them;
And it features:
- A composable operation system for lifecycle workflows;
- Deterministic execution graph with dependency resolution;
- Explicit state tracking per operation, with forward and backward system for safe rollback (eg. on failure)
- Framework agnostic design though initially and supporting django.
So why ox-orch?
The initial reason was to allow application installation by end-user from a django running instance (we not there yet, though most of the work has been done to allow this ultimate goal). What it means is that we also need a way for deployment to run nice and being able to reverse it without breaking everything meanwhile – and you know how fast it may come.
First examples
A simple installation pipeline would look like this (for the CLI tool, but you can use python libraries too):
# install.yaml
name: Pip Install
operation: "install:pip"
Once the pipeline is defined, you have to provide parameters, as context file:
# context.yaml
install:
packages:
httpx: 0.28.1
pyyaml: 6.0.3
To run:
ox-orch run -c context.yaml apply install.yaml
Whenever the pipeline fails, we can ensure to rollback changes made by the tool.
You can also run sequential operations from within a plan:
# install.yaml
name: Pip Install
operation:
__type_id__: plan
operations:
# Our installation
- "pip:install"
# Simple shell invokation
- __type_id__: shell
forward: ["echo", "Installed!"]
backward: ["echo", "Rolling-back"]
Usage with django
Here is a basic Django application installation pipeline, just for the sake of example. Though you should check on the doc for an understanding of what is going on:
name: Django App install
operation:
__type_id__: apps
# Use UV to install packages
install: install:uv
operations:
# Ensure installed packages are enabled
- "django:enable"
# Fork into a new subprocess ensuring django reinitialization
- __type_id__: fork
# This operation wraps: setup, migrate, collectstatic, compilemessages
operation:
"django:reconciliation"
Context file:
# Django project configuration
django:
project_path: "/path/to/the/project"
settings_module: "my_project.settings"
# Apps management
apps:
apps: ["ox-fin"]
# Application store
store_backend: file
store_args:
path: "./path/to/app_store.yaml"
# Configure app state store
state_store_backend: file
state_store_args:
path: "./path/to/app_state_store.yaml"
Whats next?
I’m still on the development of the project on my available time, and lots needs to happen.
Currently we have a working framework and command line tools, and multiple concepts have been validated. However we still have work to do:
- More operations, as database snapshot/restore, more UV and Poetry operations, launch and stop services (TBD, as for supervisorctl, docker or whatever)
- Documentation improvment:
- Provide examples;
- Some hidden TODOs and FIXMEs in the code.
- Improve the CLI tool: as allowing to continue an interrupted pipeline, replay and inspection, etc
- … and a running server to run pipelines through API (aka => allow to install Django applications and restart it).