How to Create a Python Virtual Environment on Ubuntu

Creating a Python virtual environment on Ubuntu isolates project dependencies, preventing package conflicts when multiple projects require different library versions. The virtualenv tool creates self-contained directories with independent Python interpreters and packages, letting you maintain clean separation between development environments without affecting the system-wide Python installation.

Virtual environments solve common development problems: testing new packages without breaking existing projects, maintaining different Django or Flask versions across applications, and ensuring production deployments match development environments exactly. When you install packages globally with sudo pip, every project shares those versions; upgrading a dependency for one application can break another. Virtual environments eliminate this risk by giving each project its own isolated package directory.

This guide covers installing virtualenv on Ubuntu, creating and activating virtual environments, and managing packages with pip. Youโ€™ll learn the complete workflow from initial setup to installing project-specific dependencies in isolated environments.

This guide covers Ubuntu 24.04 LTS and Ubuntu 22.04 LTS. Commands work identically across both versions, though Python versions differ: Ubuntu 24.04 ships with Python 3.12, while Ubuntu 22.04 includes Python 3.10. Expected output examples reflect Ubuntu 24.04.

Pre-Installation Steps Before Creating Python Virtual Environment

Update Ubuntu

Before proceeding with the installation, refresh your Ubuntu package lists so you install the latest available packages. Open your terminal by pressing Ctrl+Alt+T and run:

sudo apt update

Running apt update refreshes your package index, ensuring you install the latest available versions rather than cached older releases. If you want to upgrade everything after reviewing the changes, run sudo apt upgrade. For automated security updates, consider configuring unattended upgrades on Ubuntu.

Install Python (Skip if Installed)

Most Ubuntu installations include Python 3 by default, but minimal container images and cloud instances may omit it. Check if Python is already installed by running:

python3 --version

Expected output showing the installed Python version:

Python 3.12.3

If the command returns โ€œcommand not found,โ€ install Python with:

sudo apt install python3

This installs the default Python 3 version from the Ubuntu repositories (Python 3.12 on Ubuntu 24.04, Python 3.10 on Ubuntu 22.04).

Install Virtual Environment (virtualenv)

To create isolated Python environments, you need the virtualenv package. This tool manages separate project environments, each with its own dependencies. First, verify whether virtualenv is already available on your system:

virtualenv --version

Expected output if virtualenv is installed:

virtualenv 20.25.0+ds from /usr/lib/python3/dist-packages/virtualenv/__init__.py

If the command returns โ€œcommand not found,โ€ install the package with APT:

sudo apt install python3-virtualenv

After installation completes, virtualenv is ready to create isolated Python environments for different projects.

Choose Your Virtual Environment Tool

Understanding venv vs virtualenv Differences

Python offers two primary tools for creating virtual environments: the built-in venv module and the third-party virtualenv package. Understanding the differences helps you choose the right tool for your workflow.

The venv module ships with Python 3.3+ and requires no separate installation beyond the python3-venv package on Ubuntu. It provides lightweight virtual environments using symlinks and integrates directly with Pythonโ€™s standard library. This makes it ideal for straightforward project isolation where you need basic dependency management without additional features.

In contrast, virtualenv offers advanced capabilities like faster environment creation, support for older Python versions, and more configuration options. It works across Python 2 and Python 3 (though Python 2 reached end-of-life in 2020), and provides features like environment cloning and customizable activation scripts. Choose virtualenv when you need these advanced features or manage legacy projects.

Which Tool Should You Choose?

For most Ubuntu users working with modern Python 3 projects, venv delivers everything needed with zero installation overhead. This guide covers both approaches, starting with virtualenv for its broader feature set, then demonstrating venv as a streamlined alternative.

Create a Virtual Environment with Python

Create the Virtual Environment

Once you have Python and virtualenv installed, you can create a virtual environment. This environment is a self-contained directory that holds your projectโ€™s Python interpreter and any necessary packages. To create a virtual environment, use the following command:

virtualenv env

In this command, virtualenv is the tool youโ€™re using, and env is the name of your virtual environment. You can replace env with any name you prefer for your projectโ€™s environment.

Expected output confirming successful creation:

created virtual environment CPython3.12.3.final.0-64 in 224ms
  creator CPython3Posix(dest=/tmp/env, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
    added seed packages: pip==24.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

To target a specific Python interpreter version, use the -p flag followed by the interpreter path or version:

virtualenv -p python3.12 .venv

The -p flag specifies which Python interpreter to use when creating the environment. This is useful when you have multiple Python versions installed and need to ensure your project uses a specific version. Common environment names include env, .venv, or venv. The dot prefix hides the directory in file listings.

The created directory contains the complete virtual environment structure:

env/
โ”œโ”€โ”€ .gitignore    # Automatically excludes __pycache__ directories
โ”œโ”€โ”€ bin/          # Activation scripts and Python executables
โ”œโ”€โ”€ lib/          # Python standard library and installed packages
โ””โ”€โ”€ pyvenv.cfg    # Configuration file with Python version info

This structure isolates your projectโ€™s Python interpreter, libraries, and scripts from the system installation.

Activate the Virtual Environment

Once your virtual environment is set up, the next step is to activate it. Activating the environment allows you to work within it, using its isolated Python interpreter and packages. To activate your virtual environment, use the following command:

source env/bin/activate

Here, source is a shell command that reads and executes commands from the file specified. In this case, env/bin/activate is the file that activates your environment. Remember to replace env with your virtual environmentโ€™s name if you named it differently.

Confirming Activation

After successful activation, your terminal prompt displays the environment name as a prefix. For instance, if your virtual environment is named env, your terminal prompt will show:

(env) joshua@ubuntu-linux:~$ 

The (env) prefix serves as your primary visual indicator that youโ€™re working within an isolated environment. As a result, any Python packages you install while the environment is active will be installed within this isolated environment, not affecting the global Python installation.

Deactivate the Virtual Environment

When you finish working on a project, deactivate the virtual environment to return to your systemโ€™s default Python installation:

deactivate

After running this command, the environment name prefix disappears from your terminal prompt, and any subsequent Python or pip commands use the system-wide installation instead of the virtual environment. You donโ€™t need to deactivate before closing your terminal; simply closing the terminal window automatically ends the virtual environment session. However, if you plan to switch between multiple projects in the same terminal session, explicitly deactivating ensures you donโ€™t accidentally install packages into the wrong environment.

Alternative Method: Using Pythonโ€™s Built-in venv Module

Python includes the venv module as a built-in tool for creating virtual environments without installing third-party packages. This method offers a lightweight alternative that works identically to virtualenv for most use cases.

Install python3-venv Package

Ubuntu systems require the python3-venv package to enable the venv module. Install it using:

Check whether the package is already installed before proceeding:

apt list --installed python3-venv

Expected output if the package is installed:

python3-venv/noble-updates,noble-security,now 3.12.3-0ubuntu2.1 amd64 [installed]

If you see the [installed] marker, you can skip to the creation steps. Otherwise, install the support package with:

sudo apt install python3-venv

This package provides the necessary components for creating virtual environments with Pythonโ€™s standard library.

Create Virtual Environment with venv

Once installed, create a virtual environment using the python3 -m venv command followed by your desired environment name:

python3 -m venv myproject

This creates a directory named myproject containing the Python interpreter, pip, and supporting files. The -m flag tells Python to run the venv module as a script. Unlike virtualenv, venv creates environments silently without verbose output. Verify creation succeeded by checking the directory exists:

ls -la myproject/

Expected output showing the environment structure:

drwxr-xr-x 2 user user 4096 Dec 13 10:40 bin
drwxr-xr-x 3 user user 4096 Dec 13 10:40 include
drwxr-xr-x 3 user user 4096 Dec 13 10:40 lib
lrwxrwxrwx 1 user user    3 Dec 13 10:40 lib64 -> lib
-rw-r--r-- 1 user user  153 Dec 13 10:40 pyvenv.cfg

To pin a specific Python version you installed, call that interpreter explicitly:

python3.12 -m venv .venv

To bootstrap with the latest pip, setuptools, and wheel in one step, add the --upgrade-deps flag:

python3 -m venv --upgrade-deps .venv

The --upgrade-deps flag automatically downloads and installs the newest versions of pip, setuptools, and wheel during environment creation. This is particularly useful on Ubuntu 22.04, where the system pip (version 22.0.2) is significantly older than current releases. Using this flag eliminates the need to run pip install --upgrade as a separate step after activation.

Use the interpreter that matches your projectโ€™s Python version requirements to avoid compatibility issues when deploying to production servers.

Activate and Deactivate venv Environments

Activation works identically to virtualenv. Navigate to your project directory and run:

source myproject/bin/activate

Your prompt changes to show the environment name, indicating activation succeeded. To deactivate, simply use the same deactivate command as with virtualenv.

Verify Active Environment

When working with multiple environments, confirm which one is active using these verification commands:

echo $VIRTUAL_ENV

Expected output showing the full path to your active environment:

/home/username/myproject

If no environment is active, the output will be empty.

Additionally, check which Python interpreter youโ€™re using:

which python3

Expected output inside an active environment:

/home/username/myproject/bin/python3

This confirms youโ€™re using the environmentโ€™s Python binary instead of the system-wide installation at /usr/bin/python3.

To list all packages installed in your active virtual environment, use:

python -m pip list

Expected output showing installed packages (after installing requests):

Package            Version
------------------ ----------
certifi            2025.11.12
charset-normalizer 3.4.4
idna               3.11
pip                24.0
requests           2.32.5
urllib3            2.6.2

This displays every package and its version currently installed in the environment, helping you verify the environmentโ€™s state and track dependencies.

Managing Python Packages in Virtual Environments

Check pip Availability

Virtual environments created with virtualenv or python3 -m venv include pip by default. After activating your environment, confirm pip is present:

python -m pip --version

Expected output showing pip version and location:

pip 24.0 from /home/username/myproject/lib/python3.12/site-packages/pip (python 3.12)

If this fails, install pip system-wide so new environments can seed their own copy:

sudo apt install python3-pip

Update pip After Activation

After creating a virtual environment, the pip version matches your systemโ€™s default package version. Ubuntu 24.04 includes pip 24.0, while Ubuntu 22.04 ships with the older pip 22.0.2. Upgrading pip, setuptools, and wheel ensures you have the latest package installation tools with recent bug fixes and performance improvements:

python -m pip install --upgrade pip setuptools wheel

Expected output showing the upgrade process:

Collecting pip
  Downloading pip-25.3-py3-none-any.whl (1.8 MB)
Collecting setuptools
  Downloading setuptools-80.9.0-py3-none-any.whl (1.3 MB)
Collecting wheel
  Downloading wheel-0.45.1-py3-none-any.whl (72 kB)
Installing collected packages: wheel, setuptools, pip
  Attempting uninstall: pip
    Found existing installation: pip 24.0
    Uninstalling pip-24.0:
      Successfully uninstalled pip-24.0
Successfully installed pip-25.3 setuptools-80.9.0 wheel-0.45.1

The setuptools package provides build tools for Python projects, while wheel enables installation of pre-built binary packages instead of compiling from source. Upgrading all three together prevents compatibility issues when installing complex dependencies.

Install a Python Package

Install project dependencies from inside the active environment so nothing leaks into the system site packages. Replace <package_name> with the library you need:

python -m pip install <package_name>

For example, to add requests:

python -m pip install requests

Never use sudo pip on Ubuntu. Running pip with sudo writes packages to the system-wide Python directory, bypassing the virtual environment isolation and potentially conflicting with apt-managed packages. This can break system tools that depend on specific Python package versions. Always activate your virtual environment first, then run pip commands without sudo to keep dependencies isolated.

Remove a Python Package

Uninstall packages from the active environment when you no longer need them:

python -m pip uninstall <package_name>

For example, to remove requests:

python -m pip uninstall requests

Expected output prompting for confirmation:

Found existing installation: requests 2.32.5
Uninstalling requests-2.32.5:
  Would remove:
    /tmp/test_venv/lib/python3.12/site-packages/requests-2.32.5.dist-info/*
    /tmp/test_venv/lib/python3.12/site-packages/requests/*
Proceed (Y/n)? y
  Successfully uninstalled requests-2.32.5

Pip prompts for confirmation before removing packages. Type y and press Enter to proceed, or n to cancel. Add the -y flag to skip the confirmation prompt in automated scripts: python -m pip uninstall -y requests.

Managing Dependencies with requirements.txt

When collaborating on projects or deploying applications, tracking installed packages ensures everyone works with identical dependencies. Pythonโ€™s requirements.txt file provides a standard method for documenting and sharing your environmentโ€™s exact package versions.

To capture your current environmentโ€™s packages, run pip freeze while the environment is active:

python -m pip freeze > requirements.txt

This command lists all installed packages with their versions and writes them to requirements.txt. The file contents look like:

requests==2.32.5
certifi==2025.11.12
charset-normalizer==3.4.4
idna==3.11
urllib3==2.6.2

To replicate this environment on another system or in a fresh virtual environment, install from the requirements file:

python -m pip install -r requirements.txt

This installs every package listed with its specified version, ensuring consistency across development, testing, and production environments. For production deployments, consider flexible version constraints like requests>=2.32.0,<3.0 to allow minor updates while preventing breaking changes.

Always run these pip commands after activating a virtual environment to keep dependencies isolated, reproducible, and separate from your system Python packages.

Virtual Environment Best Practices

Following established conventions ensures your virtual environments remain maintainable and portable across development teams and deployment environments.

Naming Conventions

Use .venv or venv as your environment directory name. The dot prefix hides the directory in file listings on Linux (use ls -la to see hidden directories), reducing clutter in project folders. Many Python tools and IDEs recognize these standard names automatically. For example, Visual Studio Code detects .venv directories and offers to activate them when you open a Python file.

Alternatively, env or project-specific names like myproject-venv work when managing multiple environments in separate directories. Avoid spaces in environment names to prevent issues with shell commands and scripts.

Version Control Exclusion

Never commit virtual environment directories to Git or other version control systems. These directories contain thousands of files specific to your system's Python installation and take significant repository space. Instead, add your environment directory to .gitignore:

# .gitignore
venv/
.venv/
env/
ENV/

Commit your requirements.txt file instead, letting team members recreate the environment locally with python -m pip install -r requirements.txt.

Environment Recreation

Treat virtual environments as disposable infrastructure, not precious artifacts. If an environment becomes corrupted or accumulates unnecessary packages from testing, delete the directory and recreate it from your requirements.txt. This takes seconds and guarantees a clean state matching your documented dependencies:

rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

This workflow is faster than debugging strange package conflicts or figuring out which experimental packages to uninstall. Regular recreation also catches missing dependencies. If your requirements.txt is incomplete, the fresh environment will reveal gaps immediately rather than working accidentally because packages remained from earlier testing.

Common Virtual Environment Workflows

Understanding typical virtual environment usage patterns helps you apply these tools effectively in real projects.

New Project Setup

When starting a new Python project, establish the virtual environment first:

mkdir myproject
cd myproject
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install requests flask
python -m pip freeze > requirements.txt

This creates a project directory, initializes a virtual environment, upgrades pip, installs your initial dependencies, and captures them in requirements.txt. The requirements file becomes part of your project's version control, documenting exactly which packages your application needs.

Cloning an Existing Project

When working with a project that includes a requirements.txt file (if you need Git on Ubuntu, install it first):

git clone https://github.com/user/project.git
cd project
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

This pattern ensures you match the project's documented dependencies exactly. The virtual environment remains local to your clone. Other developers working on the same project maintain their own isolated environments with identical packages.

Working Across Multiple Projects

When switching between projects, deactivate the current environment before activating another:

# Working on project A
cd ~/projects/project-a
source .venv/bin/activate
python manage.py runserver
deactivate

# Switching to project B
cd ~/projects/project-b
source .venv/bin/activate
python app.py

Each project maintains its own environment with independent package versions. Project A might use Django 4.2 while Project B uses Django 5.0. Virtual environments prevent version conflicts between these incompatible dependencies.

Remove Python Virtual Environment Tools

If you no longer need virtual environment capabilities on your system, remove the installed packages and clean up any created environments.

Remove virtualenv Package

Uninstall the virtualenv package from your system:

sudo apt remove --purge python3-virtualenv

The --purge flag removes configuration files in addition to the package itself. After removing virtualenv, clean up any automatically installed dependencies:

sudo apt autoremove

This command removes packages that were installed as dependencies for virtualenv but are no longer needed by any other software.

Remove python3-venv Package

If you installed the python3-venv package for the built-in venv module, remove it with:

sudo apt remove --purge python3-venv

Follow this with autoremove to clean up dependencies:

sudo apt autoremove

Delete Virtual Environment Directories

Removing the virtualenv or venv packages does not delete existing virtual environments you created. These remain in your project directories until you manually remove them. To delete a virtual environment directory:

rm -rf /path/to/env

Replace /path/to/env with the actual path to your virtual environment directory. For example, to remove a virtual environment named .venv in your current project:

rm -rf .venv

This permanently deletes the environment directory and all installed packages within it. If you're using version control, ensure your .gitignore already excludes these directories so you don't accidentally commit them before removal.

Troubleshooting Common Issues

python3: command not found

If you see this error when trying to check Python version or create virtual environments, Python 3 is not installed on your system. This commonly occurs in minimal container images or fresh cloud instances.

Install Python 3 using:

sudo apt update
sudo apt install python3

Verify the installation by checking the version:

python3 --version

ensurepip is not available

When creating a virtual environment with python3 -m venv, you might encounter this error:

Error: Command '['/path/to/venv/bin/python3', '-m', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.

This indicates the python3-venv package is missing. Install it with:

sudo apt install python3-venv

After installation, try creating the virtual environment again.

Permission Denied When Installing Packages

If pip commands fail with permission errors, you likely forgot to activate your virtual environment. The error looks like:

PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.12/site-packages/...'

This happens when pip tries to install packages to the system-wide Python directory instead of your virtual environment. Activate your environment first:

source /path/to/env/bin/activate

Then retry the pip install command. Verify activation by checking for the environment name prefix in your terminal prompt.

Virtual Environment Broken After System Python Upgrade

After upgrading Ubuntu or updating Python packages, existing virtual environments may break with errors like:

Error: unsupported locale setting

Or commands fail because the Python interpreter path no longer exists. Virtual environments use symlinks to the system Python, so major Python updates can break these links.

The solution is to recreate the environment. First, export your dependencies:

source /path/to/env/bin/activate
python -m pip freeze > requirements.txt
deactivate

Delete the broken environment and create a fresh one:

rm -rf /path/to/env
python3 -m venv /path/to/env
source /path/to/env/bin/activate
python -m pip install -r requirements.txt

This recreates the environment with the updated Python interpreter and reinstalls all packages at their documented versions.

Conclusion

Python virtual environments isolate project dependencies on Ubuntu, preventing package conflicts across projects. The virtualenv tool creates these isolated environments, while pip manages packages within them. Your Ubuntu system now supports multiple Python projects with independent dependency chains, each activated and managed through simple terminal commands.

Leave a Comment