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 pip refuses 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

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.