Version Rollback
Imagine this scenario: your latest environment update broke your team’s pipeline. You know version 2.0 was working fine last week. How do you get everyone back to that version quickly?
This example walks through versioning and rollback: Alice publishes multiple versions of an environment, discovers a problem, and rolls back to a known good version.
graph LR
A["v1.0"] --> B["v2.0 ✓"] --> C["v3.0"] --> D["v4.0 ✗"]
D -->|rollback| B
What You’ll Need
Section titled “What You’ll Need”- Nebi CLI installed
- Pixi installed
- Access to a Nebi server (see Server Setup)
Step 1: Create and push the initial version
Section titled “Step 1: Create and push the initial version”Alice creates an environment with scikit-learn and a training task.
Clone the example to follow along with this tutorial:
git clone https://github.com/nebari-dev/nebi.gitcd nebi/docs/examples/ml-pipelinenebi initHere’s her pixi.toml:
[workspace]name = "ml-pipeline"channels = ["conda-forge"]platforms = ["linux-64", "linux-aarch64", "osx-arm64", "osx-64"]version = "0.1.0"
[dependencies]python = ">=3.11"scikit-learn = ">=1.4"
[tasks]train = """python -c "from sklearn.datasets import load_irisfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score
X, y = load_iris(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = DecisionTreeClassifier(random_state=42)model.fit(X_train, y_train)
y_pred = model.predict(X_test)print(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')" """After creating the environment, Alice runs the training task to verify it works:
pixi run trainAccuracy: 1.00Then pushes it to the server as v1.0:
nebi login http://localhost:8460nebi push ml-pipeline:v1.0Step 2: Push more versions
Section titled “Step 2: Push more versions”Over the next few weeks, Alice updates the environment. Each push creates a new tagged version on the server.
v2.0 adds pandas for data exploration:
pixi add "pandas>=2.2"nebi push ml-pipeline:v2.0v3.0 updates the train task to load data from a CSV file instead of the built-in dataset:
Alice edits the train task in pixi.toml to use pandas:
train = """python -c "import pandas as pdfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score
df = pd.read_csv('data.csv')X, y = df.drop('target', axis=1), df['target']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = DecisionTreeClassifier(random_state=42)model.fit(X_train, y_train)
y_pred = model.predict(X_test)print(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')" """nebi push ml-pipeline:v3.0v4.0 adds matplotlib for plotting:
pixi add "matplotlib>=3.8"nebi push ml-pipeline:v4.0Step 3: Discover the problem
Section titled “Step 3: Discover the problem”A teammate pulls the latest version and runs the training task:
pixi run trainFileNotFoundError: [Errno 2] No such file or directory: 'data.csv'The task fails because v3.0 changed it to read from a CSV file that doesn’t exist.
To figure out which version introduced the broken task, Alice looks at the version history:
nebi workspace tags ml-pipelineTAG VERSION CREATEDv4.0 5 2026-04-01 03:01v3.0 4 2026-04-01 03:01v2.0 3 2026-04-01 03:00v1.0 2 2026-04-01 03:00To narrow it down, Alice compares each pair of consecutive versions:
nebi diff ml-pipeline:v3.0 ml-pipeline:v4.0--- ml-pipeline:v3.0+++ ml-pipeline:v4.0@@ pixi.toml @@ [dependencies]+matplotlib = ">=3.8"No task changes, just a new package. She checks the previous pair:
nebi diff ml-pipeline:v2.0 ml-pipeline:v3.0--- ml-pipeline:v2.0+++ ml-pipeline:v3.0@@ pixi.toml @@ [tasks]-train = "python -c \"\nfrom sklearn.datasets import load_iris\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n\nmodel = DecisionTreeClassifier(random_state=42)\nmodel.fit(X_train, y_train)\n\ny_pred = model.predict(X_test)\nprint(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')\n\" "+train = "python -c \"\nimport pandas as pd\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\ndf = pd.read_csv('data.csv')\nX = df.drop('target', axis=1)\ny = df['target']\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n\nmodel = DecisionTreeClassifier(random_state=42)\nmodel.fit(X_train, y_train)\n\ny_pred = model.predict(X_test)\nprint(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')\n\" "There it is. The train task in v3.0 reads from data.csv instead of the built-in dataset. Alice now knows to roll back to v2.0.
Step 4: Roll back
Section titled “Step 4: Roll back”Alice rolls back by pulling the last known good version:
nebi pull ml-pipeline:v2.0Pulled ml-pipeline:v2.0This replaces the local pixi.toml and pixi.lock with the v2.0 spec. To verify that the task works again, Alice runs it:
pixi run trainAccuracy: 1.00The environment is now back to a working state!
Step 5: Roll back on the server
Section titled “Step 5: Roll back on the server”To restore the working version, Alice opens the Nebi UI, expands the version tagged v2.0, and clicks Rollback to This Version:

This creates a new version marked as Current, with the same content as v2.0:

The team can now pull the latest version to get the working environment:
nebi pull ml-pipelineWhat Just Happened
Section titled “What Just Happened”Here’s the full flow at a glance:
| Step | Command |
|---|---|
| Push initial version | nebi push :v1.0 |
| Push updates | nebi push :v2.0, :v3.0, :v4.0 |
| View version history | nebi workspace tags |
| Compare versions | nebi diff :v2.0 :v4.0 |
| Roll back on server | Nebi UI rollback button |
| Pull working version | nebi pull |
With nebi, every push is versioned and tagged. Rolling back is one click in the UI.
Next Steps
Section titled “Next Steps”- See all CLI commands: CLI Reference