How to Properly Isolate Multiple Tutor Open edX Projects Using TVM (Without Conflict)

Hi team,

I’m currently working with Tutor Open edX v19.0.1 using TVM (Turing Virtual Machine) on my development machine. I have two different Tutor environments set up for two projects:

  • v19.0.1@tvm-edtech
  • v19.0.1@tvm-titan (currently active)

When I stop one environment using:

tutor dev stop
tvm off

And then switch to the other project with:

source .tvm/bin/activate 
tutor dev restart all or tutor dev start -d

But then the second project doesn’t work properly:

  • My custom apps or XBlocks are missing
  • If I installed any Python packages or plugins, they’re not available
  • It shows errors like “module not found” for apps I had already installed
  • And if I switch back to the first one, the same problems happen there too.

This seems Docker volumes, Python environments, or Tutor data are being shared between both TVM environments — causing data and configuration to be overwritten or lost.

What I’m Trying to Do:

I want to run two or more Tutor projects using the same Open edX version (v19.0.1) on my local system, with:

  • Separate custom apps and plugins
  • No conflict or data loss between projects

My Question:

  • How can I configure TVM + Tutor so that each project stays completely isolated, even if they share the same Open edX version?

  • Or is there a better approach than TVM for running multiple Tutor-based Open edX projects locally for development?

Any advice or examples would be much appreciated. Thank you!

You don’t need TVM, you just have to set TUTOR_ROOT and TUTOR_PLUGINS_ROOT to more useful values, and there are nice general-purpose tools like mise to help you do that automatically. Here’s a section from OpenCraft’s onboarding docs that I wrote about how to do this:

Generally, you can follow the Tutor documentation for how to install and set up Tutor for a specific Open edX release. But before you do that, we highly recommend you set up a virtual environment manager to manage the python virtual environment for your new devstack. You can use mise, uv, direnv, pyenv, asdf, or any similar tool of your choice. In particular, we recommend that you use that tool to set the environment variable TUTOR_ROOT to the directory of your devstack. That variable determines where Tutor keeps all of its data and changing it from the default will help you in two ways: (1) it keeps your various devstacks isolated from each other, and (2) it makes it easier to find, inspect, and modify the important Tutor data files like config.yml.

Here is an example of creating a new “Sumac” release Open edX devstack using Tutor 19 and mise:

mkdir tutor-sumac
cd tutor-sumac
mise use python@3.12
# Tell mise to create a venv here instead of using a shared python install:
mise config set env._.python.venv.path .venv
mise config set env._.python.venv.create true
# Tell Tutor to store its data here, separate from other devstacks:
mise set TUTOR_ROOT=$(pwd)
mise set TUTOR_PLUGINS_ROOT=$(pwd)/plugins

# Set up Tutor 19 (Open edX Sumac)
pip install 'tutor[full]>=19.0.0,<20.0.0'
# If you have uv installed globally, prefix the command above with uv, as pip isn't available in the venv
# uv pip install 'tutor[full]>=19.0.0,<20.0.0'

# Set up an editable version of edx-platform (Optional)
# This would work, but is slow and takes up a lot of disk space:
#     git clone -b open-release/sumac.master --single-branch git@github.com:openedx/edx-platform.git
# So if you have an existing checkout of edx-platform (e.g. master), just create a new worktree with the branch we need:
#     cd existing edx-platform repo ; add new worktree for this new tutor instance (e.g. 'tutor-sumac'); cd back
cd ../tutor-master/edx-platform ; git worktree add ../../tutor-sumac/edx-platform open-release/sumac.master ; cd -
tutor mounts add ./edx-platform

# Launch the devstack
tutor images build openedx-dev
tutor dev launch

# Setup
tutor dev do createuser --staff --superuser YourName yourname@opencraft.com
tutor dev do importdemocourse

Access your new devstack at the URLs printed at the end of the tutor dev launch step.

With this sort of setup, you can have many different devstacks like ~/tutor-master, ~/tutor-sumac, ~/tutor-teak, and they’ll all “just work” because your environment manager like mise or direnv will automatically activate the correct virtual env and TUTOR_ environment variables based on which folder you are in.

And I believe that as long as you follow these steps, you can have the same versions running with completely separate data (e.g. ~/tutor-sumac-A, ~/tutor-sumac-B). Just note that if you want to use the exact same version of edx-platform, skip the fancy “shared worktree” cloning I mentioned above and just to a regular git clone, because the shared worktree approach does not allow you to have the same branch (e.g. sumac) checked out in multiple repos.

1 Like