Skip to content
Latchkey

pyenv-virtualenv: Per-Project Python Envs in CI

pyenv virtualenv <python> <name> builds a virtualenv on top of a pyenv-managed Python, and a matching .python-version line auto-activates it.

The pyenv-virtualenv plugin layers virtualenv management on pyenv so a project pins both a Python version and an isolated environment. Auto-activation depends on the init eval being present.

What it does

pyenv-virtualenv extends pyenv with pyenv virtualenv to create named environments and, when pyenv virtualenv-init is eval'd, auto-activates the env named in a directory's .python-version. Without that init hook, you must pyenv activate manually.

Common usage

bash
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"   # enables auto-activate
pyenv install -s 3.12.3
pyenv virtualenv 3.12.3 myapp-3.12
pyenv local myapp-3.12              # writes .python-version
pip install -r requirements.txt

Options

Command / flagWhat it does
pyenv virtualenv <py> <name>Create a virtualenv on a pyenv Python
pyenv activate <name>Activate an env manually
pyenv local <name>Pin the env via .python-version
pyenv virtualenvsList virtualenvs
eval "$(pyenv virtualenv-init -)"Enable auto-activation on cd
pyenv uninstall <name>Remove a virtualenv

In CI

CI shells are non-interactive, so the auto-activate hook may not fire; call pyenv activate <name> explicitly or rely on shims via pyenv local. Eval both pyenv init - and pyenv virtualenv-init - in each step. Cache ~/.pyenv to keep envs across runs.

Common errors in CI

"pyenv: no such command 'virtualenv'" means the pyenv-virtualenv plugin is not installed under $(pyenv root)/plugins. "Failed to activate virtualenv" or the env not activating is usually the missing virtualenv-init eval in a non-interactive shell. "version `myapp-3.12' is not installed" means the .python-version names an env that was never created on this runner.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →