The Problem with System Python
On most Linux distributions, Python is a core system tool. Debian and Ubuntu ship with Python 3 pre-installed because system utilities depend on it. This creates a fundamental tension: you need a specific Python version for your project, but modifying the system Python can break OS-level scripts and tools.
The solution is to never touch system Python and instead manage your own Python installations independently. Here's how to do it cleanly.
Step 1: Install pyenv
pyenv lets you install and switch between multiple Python versions without touching the system installation. Install it via the official installer:
curl https://pyenv.run | bash
Then add the following to your ~/.bashrc or ~/.zshrc:
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
Reload your shell: source ~/.bashrc
Step 2: Install Build Dependencies
pyenv compiles Python from source, so you need build dependencies first. On Debian/Ubuntu:
sudo apt update && sudo apt install -y \
build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev \
libncursesw5-dev xz-utils tk-dev libxml2-dev \
libxmlsec1-dev libffi-dev liblzma-dev
Step 3: Install a Python Version
List available Python versions with pyenv install --list, then install your preferred version:
pyenv install 3.12.3
pyenv global 3.12.3
Verify with python --version. You can also set a per-project version using pyenv local 3.11.8 inside a project directory — this writes a .python-version file that pyenv picks up automatically.
Step 4: Use Virtual Environments for Every Project
Even with pyenv, you should always use a virtual environment per project to isolate dependencies. Python's built-in venv module is sufficient:
cd ~/projects/my-app
python -m venv .venv
source .venv/bin/activate
Once activated, your prompt changes and pip install affects only this environment. To deactivate: simply run deactivate.
Step 5: Manage Dependencies with pip and a requirements file
Install packages inside your virtual environment and freeze them to a file:
pip install requests flask
pip freeze > requirements.txt
Anyone cloning your project can recreate the environment with:
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
Optional: Use pipx for CLI Tools
For Python-based command-line tools (like black, httpie, or cookiecutter), use pipx rather than installing them into your global environment. pipx installs each tool in its own isolated environment but makes it available system-wide:
pip install pipx
pipx install black
pipx install httpie
Quick Reference
| Task | Command |
|---|---|
| Install Python version | pyenv install 3.12.3 |
| Set global Python | pyenv global 3.12.3 |
| Create virtual env | python -m venv .venv |
| Activate virtual env | source .venv/bin/activate |
| Freeze dependencies | pip freeze > requirements.txt |
| Install CLI tool | pipx install tool-name |
With this setup you get a clean, reproducible, and maintainable Python workflow that won't interfere with your system — now or in the future.