Installing Major Python Versions on Debian Trixie Very, very often you have to deal with the need to use a certain version of Python, for example, for torch, or for something specific. Using conda or Docker with nvidia-container-toolkit and then setting up images like nvidia/cuda:13.0.1-runtime-ubuntu22.04 feels counterintuitive to me, even though I’ve done it many times. And an additional packages have to be installed in the container. It’s easier and more convenient to compile everything on the host system, but at the same time prevent contamination of the entire system with third-party libraries and executable files. The following is an example of building multiple Python versions for the verpy group only, which is a bit more convenient than installing for just one user.
ai - an arbitrary user from whom the compilation is performed. verpy - the group that will be allowed to use these versions. 1
2
3
4
apt install \
build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev \
liblzma-dev libgdbm-dev libnsl-dev libgdbm-compat-dev
mkdir /opt/openssl mkdir /opt/python groupadd --gid 42398 verpy usermod -aG verpy ai
Provide write access for the installation chown ai:verpy /opt/openssl /opt/python chmod u=rwX,g=rX,o-rwXx /opt/openssl /opt/python
Switch to the user from whom the build and installation will be performed su ai mkdir -p $HOME/src/openssl cd $HOME/src/openssl
Installing the required versions of openssl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 1.0.2u > python 3.7
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_0_2u/openssl-1.0.2u.tar.gz
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_0_2u/openssl-1.0.2u.tar.gz.asc
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_0_2u/openssl-1.0.2u.tar.gz.sha256
gpg --keyserver keys.gnupg.net --recv-keys 8657ABB260F056B1E5190839D9C4D26D0E604491
gpg --verify openssl-1.0.2u.tar.gz.asc
tar zxf openssl-1.0.2u.tar.gz && cd openssl-1.0.2u
./config --prefix = /opt/openssl/1.0.2u --openssldir = /opt/openssl/1.0.2u/ssl
make -j8
make install_sw
# exec bash - reinitializes and resets any environment variables that may remain from a previous installation
exec bash
cd $HOME /src/openssl
# 1.1.1w > python 3.9
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1w/openssl-1.1.1w.tar.gz
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1w/openssl-1.1.1w.tar.gz.asc
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1w/openssl-1.1.1w.tar.gz.sha256
gpg --keyserver keys.gnupg.net --recv-keys EFC0A467D613CB83C7ED6D30D894E2CE8B3D79F5
gpg --verify openssl-1.1.1w.tar.gz.asc
tar zxf openssl-1.1.1w.tar.gz && cd openssl-1.1.1w
./config --prefix = /opt/openssl/1.1.1w --openssldir = /opt/openssl/1.1.1w/ssl
make -j8
make install_sw
exec bash
cd $HOME /src/openssl
# 3.0.17 > python 3.10 ; 3.11
wget https://github.com/openssl/openssl/releases/download/openssl-3.0.17/openssl-3.0.17.tar.gz
wget https://github.com/openssl/openssl/releases/download/openssl-3.0.17/openssl-3.0.17.tar.gz.asc
wget https://github.com/openssl/openssl/releases/download/openssl-3.0.17/openssl-3.0.17.tar.gz.sha256
gpg --keyserver keys.gnupg.net --recv-keys BA5473A2B0587B07FB27CF2D216094DFD0CB81EF
gpg --verify openssl-3.0.17.tar.gz.asc
tar zxf openssl-3.0.17.tar.gz && cd openssl-3.0.17
./config --prefix = /opt/openssl/3.0.17 --openssldir = /opt/openssl/3.0.17/ssl
make -j8
make install_sw
exec bash
cd $HOME /src/openssl
# 3.5.4 > python 3.12
wget https://github.com/openssl/openssl/releases/download/openssl-3.5.4/openssl-3.5.4.tar.gz
wget https://github.com/openssl/openssl/releases/download/openssl-3.5.4/openssl-3.5.4.tar.gz.asc
wget https://github.com/openssl/openssl/releases/download/openssl-3.5.4/openssl-3.5.4.tar.gz.sha256
gpg --keyserver keys.gnupg.net --recv-keys BA5473A2B0587B07FB27CF2D216094DFD0CB81EF
gpg --verify openssl-3.5.4.tar.gz.asc
tar zxf openssl-3.5.4.tar.gz && cd openssl-3.5.4
./config --prefix = /opt/openssl/3.5.4 --openssldir = /opt/openssl/3.5.4/ssl
make -j8
make install_sw
exec bash
cd $HOME /src
Installing Python 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
mkdir -p $HOME /src/python
cd $HOME /src/python
# python 3.7.17
wget https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tar.xz
wget https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
gpg --verify Python-3.7.17.tar.xz.asc
tar xvf Python-3.7.17.tar.xz && cd Python-3.7.17
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/1.1.1w/lib" ./configure --prefix = /opt/python/3.7.17 --enable-optimizations --with-openssl = /opt/openssl/1.1.1w --with-lto --with-computed-gotos --with-system-ffi
make -j8
make test
make install
exec bash
cd $HOME /src/python
# python 3.9.19
wget https://www.python.org/ftp/python/3.9.19/Python-3.9.19.tar.xz
wget https://www.python.org/ftp/python/3.9.19/Python-3.9.19.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys E3FF2839C048B25C084DEBE9B26995E310250568
gpg --verify Python-3.9.19.tar.xz.asc
tar xvf Python-3.9.19.tar.xz && cd Python-3.9.19
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/1.1.1w/lib" ./configure --prefix = /opt/python/3.9.19 --enable-optimizations --with-openssl = /opt/openssl/1.1.1w --with-lto --with-computed-gotos --with-system-ffi
make -j8
make test
make install
exec bash
cd $HOME /src/python
# python 3.9.25
wget https://www.python.org/ftp/python/3.9.25/Python-3.9.25.tar.xz
wget https://www.python.org/ftp/python/3.9.25/Python-3.9.25.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys E3FF2839C048B25C084DEBE9B26995E310250568
gpg --verify Python-3.9.25.tar.xz.asc
tar xvf Python-3.9.25.tar.xz && cd Python-3.9.25
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/1.1.1w/lib" ./configure --prefix = /opt/python/3.9.25 --enable-optimizations --with-openssl = /opt/openssl/1.1.1w --with-lto --with-computed-gotos --with-system-ffi
make -j8
make test
make install
exec bash
cd $HOME /src/python
# python 3.10.19
wget https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tar.xz
wget https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys CFDCA245B1043CF2A5F97865FFE87404168BD847
gpg --verify Python-3.10.19.tar.xz.asc
tar xvf Python-3.10.19.tar.xz && cd Python-3.10.19
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/3.0.17/lib" ./configure --prefix = /opt/python/3.10.19 --enable-optimizations --with-openssl = /opt/openssl/3.0.17 --with-lto --with-computed-gotos --with-system-ffi
make -j8
make test
make install
exec bash
cd $HOME /src/python
# python 3.11.14
wget https://www.python.org/ftp/python/3.11.14/Python-3.11.14.tar.xz
wget https://www.python.org/ftp/python/3.11.14/Python-3.11.14.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys CFDCA245B1043CF2A5F97865FFE87404168BD847
gpg --verify Python-3.11.14.tar.xz.asc
tar xvf Python-3.11.14.tar.xz && cd Python-3.11.14
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/3.0.17/lib" ./configure --prefix = /opt/python/3.11.14 --enable-optimizations --with-openssl = /opt/openssl/3.0.17 --with-lto --with-computed-gotos --with-system-ffi
make -j8
make test
make install
exec bash
cd $HOME /src/python
# python 3.12.12
wget https://www.python.org/ftp/python/3.12.12/Python-3.12.12.tar.xz
wget https://www.python.org/ftp/python/3.12.12/Python-3.12.12.tar.xz.asc
gpg --keyserver keys.gnupg.net --search-keys 7169605F62C751356D054A26A821E680E5FA6305
gpg --verify Python-3.12.12.tar.xz.asc
tar xvf Python-3.12.12.tar.xz && cd Python-3.12.12
LDFLAGS = " ${ LDFLAGS } -Wl,-rpath=/opt/openssl/3.5.4/lib" ./configure --prefix = /opt/python/3.12.12 --enable-optimizations --with-openssl = /opt/openssl/3.5.4 --with-lto --with-computed-gotos
make -j8
make test
make install
exec bash
strip - it’s up to you 1
2
3
4
5
6
7
8
9
10
11
12
13
14
# [ --strip-all | --strip-unneeded ]
strip --strip-unneeded /opt/python/3.10.19/bin/python3.10
strip --strip-unneeded /opt/python/3.11.14/bin/python3.11
strip --strip-unneeded /opt/python/3.12.12/bin/python3.12
strip --strip-unneeded /opt/python/3.7.17/bin/python3.7
strip --strip-unneeded /opt/python/3.7.17/bin/python3.7m
strip --strip-unneeded /opt/python/3.9.19/bin/python3.9
strip --strip-unneeded /opt/python/3.9.25/bin/python3.9
strip --strip-unneeded /opt/openssl/1.0.2u/bin/openssl
strip --strip-unneeded /opt/openssl/1.1.1w/bin/openssl
strip --strip-unneeded /opt/openssl/3.0.17/bin/openssl
strip --strip-unneeded /opt/openssl/3.5.4/bin/openssl
exit
Now let’s take away the write access That’s it, OpenSSL and Python are installed, write access may must be removed. Read, write, and execute permissions only for the verpy group. All other users will not interact with these packages in any way, this is not FrankenDebian.
chown -R nobody:verpy /opt/openssl /opt/python chmod -R u=r,g=rXx,o-rwXx /opt/openssl /opt/python
Linking all versions of Python Run the following script as the ai user:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
if [[ ! -d " $HOME /.local/bin" ]] ; then
mkdir -p $HOME /.local/bin
fi
declare -A dirs =(
[ "3.7.17" ]= "2to3-3.7 easy_install-3.7 idle3.7 pip3.7 pydoc3.7 python3.7 python3.7m pyvenv-3.7 python3.7m-config"
[ "3.9.25" ]= "2to3-3.9 idle3.9 pip3.9 pydoc3.9 python3.9 python3.9-config"
[ "3.10.19" ]= "2to3-3.10 idle3.10 pip3.10 pydoc3.10 python3.10 python3.10-config"
[ "3.11.14" ]= "2to3-3.11 idle3.11 pip3.11 pydoc3.11 python3.11 python3.11-config"
[ "3.12.12" ]= "2to3-3.12 idle3.12 pip3.12 pydoc3.12 python3.12 python3.12-config"
)
for dir in " ${ !dirs[@] } " ; do
printf '%s\n' " $dir "
bins = " ${ dirs [ $dir ] } "
for bin in ${ bins } ; do
printf '/opt/python/%s/bin/%s > ~/.local/bin/%s\n' " ${ dir } " " $bin " " $bin "
ln -sf /opt/python/${ dir } /bin/${ bin } $HOME /.local/bin/${ bin }
done
bins = ''
done
Some tests import ssl ssl.OPENSSL_VERSION import sys print(sys.executable) python3.7
1
2
3
4
5
6
7
8
9
Python 3.7.17 ( default, Dec 22 2025, 10:58:22)
[ GCC 14.2.0] on linux
Type "help" , "copyright" , "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.1w 11 Sep 2023'
>>> import sys
>>> print( sys.executable)
/home/ai/.local/bin/python3.7
python3.12
1
2
3
4
5
Python 3.12.12 ( main, Dec 22 2025, 12:33:21) [ GCC 14.2.0] on linux
Type "help" , "copyright" , "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 3.5.4 30 Sep 2025'
Install torch with python 3.10 1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir ~/.torch_env/
python3.10 -m venv ~/.torch_env/
source ~/.torch_env/bin/activate
which pip3
# /home/ai/.torch_env/bin/pip3
which python3.10
# /home/ai/.torch_env/bin/python3.10
python3.10 -m pip install --upgrade pip
pip3 install torch numpy
python3.10
from torch import cuda
print( cuda.get_device_name( cuda.current_device()))
1
2
3
4
5
6
python3.10
Python 3.10.19 ( main, Dec 22 2025, 11:39:18) [ GCC 14.2.0] on linux
Type "help" , "copyright" , "credits" or "license" for more information.
>>> from torch import cuda
>>> print( cuda.get_device_name( cuda.current_device()))
NVIDIA RTX A3000 Laptop GPU
If some tests fail You can continue the installation and then pass the same test under the tested version of Python:
1
2
1 test failed:
test_urllib2
cd ~/src/python/Python-3.7.17/Lib
1
2
3
/opt/python/3.7.17/bin/python3.7 -m test test_ssl
/opt/python/3.7.17/bin/python3.7 -m test test_urllib2
== Tests result: SUCCESS ==
2025-12-24 22:19 +0000