Ubuntu 24.04 uses Python 3.12 by default, but application dependencies should not be installed into the operating system's Python environment with a normal global pip install. Ubuntu follows the externally managed environment model defined by Python packaging standards, so the safe default is to install python3-pip and python3-venv with APT, create a project-specific virtual environment, and run pip inside that environment.
On a Raff Ubuntu VM, this keeps your project packages separate from files managed by the operating system. It also makes deployments easier to reproduce: each application can have its own .venv, dependency file, and package versions without changing Python packages required by system tools.
This tutorial shows how to install pip on Ubuntu 24.04, create and verify a Python virtual environment, install packages safely, work with requirements files, use pipx for standalone Python command-line applications, troubleshoot externally-managed-environment, and clean up the test environment. It uses python -m pip inside the virtual environment so the pip command is tied to the Python interpreter you actually intend to use.
Prerequisites:
- A Raff Linux VM running Ubuntu 24.04
- SSH access with a non-root user that has sudo privileges
- No public application port or firewall change is required for this tutorial
Step 1 — Verify the Ubuntu 24.04 Python Version
Check the default Python 3 interpreter:
python3 --version
Ubuntu 24.04 defaults to Python 3.12. The exact patch version can change through Ubuntu updates, so do not depend on a hard-coded 3.12.x patch number.
Check which executable is being used:
command -v python3 python3 -c 'import sys; print(sys.executable)'
On a standard Ubuntu installation, the system interpreter is normally under /usr/bin/.
Verify: python3 --version should report Python 3.12.x and sys.executable should point to the intended system Python before you create a virtual environment.
Step 2 — Install pip and venv with APT
Refresh package metadata and install the Ubuntu packages for pip and virtual environments:
sudo apt update sudo apt install -y python3-pip python3-venv
Check pip through the Python interpreter rather than relying only on a standalone pip3 command:
python3 -m pip --version
Also verify that the venv module is available:
python3 -m venv --help >/dev/null && echo 'venv available'
Using APT here matters because Ubuntu manages the system Python installation. Avoid using get-pip.py to replace the distro-managed pip on a normal Ubuntu server.
Verify: python3 -m pip --version should succeed and the venv check should print venv available.
Step 3 — Understand the externally-managed-environment Error
Ubuntu 24.04 marks its system Python as externally managed. Python packaging tools use this marker to avoid modifying packages owned by the operating system.
Locate the marker without changing the system:
python3 - <<'PY' import os import sysconfig path = os.path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED') print(path) print('exists:', os.path.exists(path)) PY
On Ubuntu 24.04, a normal system-level command such as:
python3 -m pip install requests
is expected to be rejected outside a virtual environment with an externally-managed-environment message.
pip provides --break-system-packages as an explicit override, but that bypasses the protection. Do not use it as the normal application-dependency workflow. Use a virtual environment instead.
Verify: The marker check should report that the externally managed marker exists on the distro-managed Python installation.
Step 4 — Create a Python Virtual Environment on Ubuntu
Create a project directory and a virtual environment named .venv:
mkdir -p ~/my-python-project cd ~/my-python-project python3 -m venv .venv
Python's standard venv module creates an isolated Python environment for the project. Unless --without-pip is specified, venv bootstraps pip into the environment.
Starting with Python 3.12, setuptools is no longer installed as a core venv dependency by default. Install it only when your project or build process actually requires it.
Inspect the environment:
ls -la .venv .venv/bin/python --version .venv/bin/python -m pip --version
Add the environment directory to Git ignore rules if this is a version-controlled project:
printf '.venv/\n' >> .gitignore
Verify: .venv/bin/python and .venv/bin/python -m pip should both run successfully, and .venv/ should be excluded from version control.
Step 5 — Activate the venv and Verify Which Python and pip You Are Using
Activate the environment in Bash:
source .venv/bin/activate
Check the active executables:
which python python --version python -m pip --version
The paths should now point inside ~/my-python-project/.venv/.
Using python -m pip is useful because it makes the relationship between the interpreter and pip explicit. It avoids accidentally invoking a pip executable from another Python installation on systems with multiple interpreters.
You do not have to activate a venv to use it. Automation and systemd units can call its interpreter directly:
~/my-python-project/.venv/bin/python -m pip --version
Verify: which python and the pip output should both reference the .venv directory.
Step 6 — Install and Verify a Python Package with pip
With the virtual environment active, install a small test dependency:
python -m pip install requests
Inspect the installed package:
python -m pip show requests
Verify that Python can import it:
python - <<'PY' import requests print('requests version:', requests.__version__) PY
Check the package location:
python -c 'import requests; print(requests.__file__)'
The path should be inside .venv, not the system Python directories.
This tutorial intentionally does not start a Flask development server or open a public firewall port. Installing pip and verifying a package does not require exposing an application to the internet.
Verify: requests should import successfully and its file path should be inside your project's .venv.
