There are scenarios where you need a specific version of Python available for a particular user — without modifying the system-wide Python installation or requiring root access after the initial build. Installing Python under a user’s home directory is the cleanest way to achieve this.
This guide walks through downloading, compiling, and installing Python from source into a user-specific prefix.
Prerequisites
The build process requires a few development libraries. Install them as root before switching to the target user:
# AlmaLinux / RHEL / CentOS
dnf install gcc make openssl-devel bzip2-devel libffi-devel zlib-devel readline-devel sqlite-devel -y
# Ubuntu / Debian
apt install build-essential libssl-dev libbz2-dev libffi-dev zlib1g-dev libreadline-dev libsqlite3-dev -y
If you skip this step, the build will succeed but key Python modules (ssl, hashlib, sqlite3) will be silently missing — and you’ll spend time debugging why
piprefuses to connect.
Step 1 — Log in as the target user
su - username
Or via SSH directly as that user.
Step 2 — Download the Python source
Browse available releases at https://www.python.org/downloads/source/ and pick the version you need. As of this writing, Python 3.13.13 is the latest stable long-term supported release.
wget https://www.python.org/ftp/python/3.13.13/Python-3.13.13.tgz
Verify the download integrity (optional but recommended):
sha256sum Python-3.13.13.tgz
Cross-check the hash against the value listed on the official release page.
Step 3 — Extract the archive
tar -xvf Python-3.13.13.tgz
Step 4 — Navigate to the source directory
cd Python-3.13.13
Step 5 — Configure with a user-specific prefix
The --prefix flag is what makes this a per-user install. It tells the build system to install everything — binaries, libraries, headers — under the specified directory instead of the system paths.
./configure --prefix=/home/username/python3.13 --enable-optimizations
The --enable-optimizations flag runs profile-guided optimisation during the build, resulting in a 10–20% performance improvement at the cost of a slightly longer compile time. Recommended for any non-throwaway install.
Step 6 — Compile
make -j$(nproc)
Using -j$(nproc) runs the build across all available CPU cores, significantly reducing compile time on multi-core servers.
Step 7 — Install
make install
This installs Python under /home/username/python3.13/. No system files are touched.
Step 8 — Verify the installation
/home/username/python3.13/bin/python3 --version
Expected output:
Python 3.13.13
Also confirm pip is available:
/home/username/python3.13/bin/pip3 --version
Step 9 — Add to PATH (optional but recommended)
To avoid typing the full path every time, add the user Python binary directory to the user’s PATH in ~/.bashrc:
echo 'export PATH=/home/username/python3.13/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
After this, python3 and pip3 will resolve to the user’s private installation:
which python3
# → /home/username/python3.13/bin/python3
python3 --version
# → Python 3.13.13
Troubleshooting
ssl module not available or pip fails with SSL errors
The openssl-devel (or libssl-dev) package was not installed before running ./configure. Install it, then rerun ./configure, make, and make install.
make fails with permission errors
Ensure you are running the build as the target user, not root. The --prefix path must be writable by that user.
Old Python version still showing after PATH update
Run source ~/.bashrc or open a new SSH session to reload the environment.
This approach works cleanly across AlmaLinux, RHEL, Ubuntu, and Debian. The user gets a fully self-contained Python installation they control, and the system Python is left untouched — no version conflicts, no sudoer debates.