Multi-version Python Docker image for research and testing with tox.
makukha/multipython:latest
— prerelease and supported Python distributionsmakukha/multipython:cpython
— latest bugfix CPython imagemakukha/multipython:supported
— supported versions, not including prereleasemakukha/multipython:unsafe
— all versions, including end-of-lifemakukha/multipython:{py314...}
— single version images- All images except
base
have system Python in virtual environment - All images include pip, pyenv, setuptools, tox, uv, virtualenv
- Tox and virtualenv understand multipython tag names, even non-standard
py313t
- Build your own environment from single version images
- Based on
debian:stable-slim
- Single platform
linux/amd64
# tox.ini
[tox]
env_list = py{27,35,36,37,38,39,310,311,312,313,314,313t,314t}
skip_missing_interpreters = false
[testenv]
command = {env_python} --version
docker run --rm -v .:/src -w /src makukha/multipython:unsafe tox run
Single version images can be used on their own:
$ docker run --rm -v .:/src -w /src makukha/multipython:py310 tox run
Distribution | Note | Tag | Command | Source |
---|---|---|---|---|
CPython 3.14.0a5 | free threaded | py314t |
python3.14t |
pyenv |
CPython 3.13.2 | free threaded | py313t |
python3.13t |
pyenv |
CPython 3.14.0a5 | py314 |
python3.14 |
pyenv | |
CPython 3.13.2 | system ⚙️ | py313 |
python3.13 |
pyenv |
CPython 3.12.9 | py312 |
python3.12 |
pyenv | |
CPython 3.11.11 | py311 |
python3.11 |
pyenv | |
CPython 3.10.16 | py310 |
python3.10 |
pyenv | |
CPython 3.9.21 | py39 |
python3.9 |
pyenv | |
CPython 3.8.20 | EOL | py38 |
python3.8 |
pyenv |
CPython 3.7.17 | EOL | py37 |
python3.7 |
pyenv |
CPython 3.6.15 | EOL | py36 |
python3.6 |
pyenv |
CPython 3.5.10 | EOL | py35 |
python3.5 |
pyenv |
CPython 2.7.18 | EOL | py27 |
python2.7 |
pyenv |
makukha/multipython
—py3{9,10,11,12,13,14}
,py3{13,14}t
makukha/multipython:cpython
—py313
makukha/multipython:supported
—py3{9,10,11,12,13}
,py313t
makukha/multipython:unsafe
— all tags above
All commands are on PATH
as symlinks to respective distributions. System ⚙️ Python, that is always the latest bugfix version, is available as python
in virtual environment along with pip
, tox
, and virtualenv
.
The only used source used is pyenv. However, it is planned to use python-build-standalone distributions for supported Python versions to speed up tests and image builds.
-
Check Versions section for pyenv, tox, uv, pip, setuptools versions.
-
See Status of Python versions for the list of end-of-life versions.
All single version tags above, including py313t
and py314t
, can be used as tox environment names (see example above) or as virtualenv python requests:
$ virtualenv --python py314t /tmp/venv
This is possible because two custom plugins are pre-installed in system environment (tox-multipython is installed only for tox 3). When building custom image, they are automatically added by py install
. Both plugins are part of this project, and use multipython image for self testing.
- virtualenv-multipython — discovery plugin for virtualenv and tox 4
- tox-multipython — discovery plugin for tox 3
Combine single version images to use a subset of Python distributions.
# Dockerfile
FROM makukha/multipython:base
COPY --from=makukha/multipython:py27 /root/.pyenv/versions /root/.pyenv/versions/
COPY --from=makukha/multipython:py35 /root/.pyenv/versions /root/.pyenv/versions/
COPY --from=makukha/multipython:py312 /root/.pyenv/versions /root/.pyenv/versions/
COPY --from=makukha/multipython:py313t /root/.pyenv/versions /root/.pyenv/versions/
RUN py install
All makukha/multipython
images come with helper utility
$ docker run --rm makukha/multipython py --version
multipython 252D
$ py ls -l
3.14.0a5t
3.13.2t
3.14.0a5
3.13.2
3.12.9
3.11.11
3.10.16
3.9.21
3.8.20
3.7.17
3.6.15
3.5.10
2.7.18 |
$ py ls -s
3.14t
3.13t
3.14
3.13
3.12
3.11
3.10
3.9
3.8
3.7
3.6
3.5
2.7 |
$ py ls -t
py314t
py313t
py314
py313
py312
py311
py310
py39
py38
py37
py36
py35
py27 |
$ py --help
usage: py bin {--cmd|--dir|--path} [TAG]
py info [--cached]
py install [--sys TAG] [--no-update-info]
py ls {--tag|--short|--long|--all}
py root
py sys
py tag <PYTHON>
py uninstall [--no-update-info]
py --version
py --help
commands:
bin Show Python executable command or path
info Extended details in JSON format
install Install system environment, commands, seed packages
ls List all distributions
root Show multipython root path
sys Show system python tag
tag Determine tag of executable
uninstall Uninstall system environment
binary info formats:
-c --cmd Command name, expected to be on PATH
-d --dir Path to distribution bin directory
-p --path Path to distribution binary
version formats:
-t --tag Python tag, e.g. py39, pp19
-s --short Short version without prefix, e.g. 3.9
-l --long Full version without prefix, e.g. 3.9.12
-a --all Lines 'tag short long', e.g. 'py39 3.9 3.9.3'
other options:
-c --cached Show cached results
--no-update-info Don't update local info.json (works faster)
--sys Preferred system executable
--version Show multipython distribution version
--help Show this help and exit
Every release has versions metadata in JSON format:
- inside release image as file
- inside custom images built from single versions
- in GitHub repository
- image CLI
py info -c
Every image has JSON metadata file /root/.multipython/info.json
After running py install
in custom image Dockerfile, /root/.multipython/info.json
is updated automatically.
base
– tests/share/info/base.json@v252Dcpython
– tests/share/info/cpython.json@v252Dlatest
– tests/share/info/latest.json@v252Dsupported
– tests/share/info/supported.json@v252Dunsafe
– tests/share/info/unsafe.json@v252D- (same for single version tags)
docker run --rm makukha/multipython:latest py info -c
{
"multipython": {
"version": "252D",
"subset": "latest",
"root": "/root/.multipython"
},
"pyenv": {
"version": "2.5.3",
"root": "/root/.pyenv",
"python_versions": "/root/.pyenv/versions"
},
"tox": {
"version": "4.24.1"
},
"uv": {
"version": "0.5.31",
"python_versions": "/root/.local/share/uv/python"
},
"virtualenv": {
"version": "20.29.2",
"config": "/root/.config/virtualenv/virtualenv.ini"
},
"system": {
"tag": "py313",
"root": "/root/.multipython/sys",
"command": "python",
"bin_dir": "/root/.multipython/sys/bin",
"binary_path": "/root/.multipython/sys/bin/python",
"packages": {
"cachetools": "5.5.1",
"chardet": "5.2.0",
"colorama": "0.4.6",
"distlib": "0.3.9",
"filelock": "3.17.0",
"packaging": "24.2",
"pip": "25.0.1",
"platformdirs": "4.3.6",
"pluggy": "1.5.0",
"pyproject-api": "1.9.0",
"setuptools": "75.8.0",
"tox": "4.24.1",
"tox-multipython": "0.4.0",
"virtualenv": "20.29.2",
"virtualenv-multipython": "0.5.1",
"wheel": "0.45.1"
}
},
"base_image": {
"name": "debian",
"channel": "stable-slim",
"digest": "sha256:5724d31208341cef9af6ae2be86be9cda6a87271f362a03481a522c9c19d401b"
},
"python": [
{
"version": "3.14.0a5t",
"source": "pyenv",
"tag": "py314t",
"short": "3.14t",
"command": "python3.14t",
"bin_dir": "/root/.pyenv/versions/3.14.0a5t/bin",
"binary_path": "/root/.pyenv/versions/3.14.0a5t/bin/python",
"is_system": false,
"packages": {
"pip": "25.0.1",
"setuptools": "75.8.0",
"wheel": "0.45.1"
}
},
...
Tools available in base
image have (no surprise) the same versions in all other images. For Python package versions, system
environment is used.
✨ latest versions will be updated in upcoming releases.
Image tag | pyenv | uv |
---|---|---|
base |
2.5.3 ✨ | 0.5.31 ✨ |
other images | 2.5.3 ✨ | 0.5.31 ✨ |
Image tag | pip | setuptools | tox | virtualenv | wheel |
---|---|---|---|---|---|
cpython |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
latest |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
supported |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
unsafe |
25.0.1 ✨ | 75.8.0 ✨ | 4.5.1.1 | 20.21.1 | 0.45.1 ✨ |
Image tag | pip | setuptools | tox | virtualenv | wheel |
---|---|---|---|---|---|
py314t |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py313t |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py314 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py313 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py312 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py311 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py310 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py39 |
25.0.1 ✨ | 75.8.0 ✨ | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py38 |
25.0.1 ✨ | 75.3.0 | 4.24.1 ✨ | 20.29.2 ✨ | 0.45.1 ✨ |
py37 |
24.0 | 68.0.0 | 4.8.0 | 20.26.6 | 0.42.0 |
py36 |
21.3.1 | 59.6.0 | 3.28.0 | 20.17.1 | 0.37.1 |
py35 |
20.3.4 | 50.3.2 | 3.28.0 | 20.15.1 | 0.37.1 |
py27 |
20.3.4 | 44.1.1 | 3.28.0 | 20.15.1 | 0.37.1 |
The minimal tox version v4.5.1.1 is dictated by virtualenv support of Python versions. Virtualenv v20.22 dropped support for Python 3.6, v20.27 dropped support of Python 3.7. Depending on minimal Python version used in custom environment, tox version will be automatically selected by py install
.
Min Python version | virtualenv | tox |
---|---|---|
<3.7 |
<20.22 |
<4.6 |
<3.8 |
<20.27 |
>=4.6 |
>=3.8 |
>=20.27 |
>=4.6 |
Starting from Jan 2025, multipython uses CalVer convention with Date62 based dates.
Release version format is YYMD[.patch]
YY
is25,26,...
M
is Base16 month (1
= Jan,A,B,C
= Oct, Nov, Dec)D
is Base62 day of month (from1
toV
= 31).patch
is optional numerical suffix allowing multiple releases per day
- All non-single-version targets and
py
helper tool are tested (see/tests
directory for details). - Source files are linted with Hadolint and ShellCheck.
- Check vulnerability reports provided by Docker Scout
- Use specific image digest
- Report security vulnerabilities via GitHub Security Advisories
Security vulnerabilities can come from
- Base Debian image
debian:stable-slim
- Python distributions, especially reached end-of-life
- multipython itself
$ docker run --rm -v .:/src -w /src makukha/multipython@sha256:... tox run
Image tag | Image digest |
---|---|
base-252D |
sha256:091de4a2c046d9e17d972c90d709aa0ac9b3531dfc5f66c42293382774a0246f |
cpython-252D |
sha256:a67dbfe1fad182a83e0cf91bb882961624929b96f44abf9b7fc8c70c7e0031b1 |
py27-252D |
sha256:957492d593cafa6d80c4f5b653cf5521cb46d61a989c73ea6e0af8f35614b4d8 |
py310-252D |
sha256:a578c54fe5135c101f150d398844b76f507286129bf253689c0417a5980befc1 |
py311-252D |
sha256:250b284d775b9d21d89372e6b045167216843f7a1afb758c5db2949bf3468ab0 |
py312-252D |
sha256:44d73f34d31d30ec13a01c30e5e0e0f8f2d37322fa26794ca6d65667606afdf3 |
py313-252D |
sha256:ad9b9759cb9bc36649a77aaa2f64ab9c7b0b8a97b74ae2c2d2735cb74d7c204c |
py313t-252D |
sha256:b2f433a85086e60df89630426ba113bcc98d9fac6d90bdd9c29f989d94543fd7 |
py314-252D |
sha256:81fff7432462e15c9dcd55381fe6a8baa68c02e07aa168ef06fbaac417069f97 |
py314t-252D |
sha256:c334ae77b51710008e150f043d2c6e8b021e4f1733fcbcaba141523c8487bf22 |
py35-252D |
sha256:96ab4482164badc273752caae3a402d9663a34639f7d98d14f7ae475181519e2 |
py36-252D |
sha256:e3bbbfedf59f80f74a2d7ef55f9753e3c65fc0f5cef1deae508ef2cb12569ed7 |
py37-252D |
sha256:811c5b9e2dc1904334af3e04c0934a61b094cf60210ad91bc7f62d49e4d54ede |
py38-252D |
sha256:853aa94521454d6c9cfd2fee22b8dba952cb765772b180fe30527b992509c9d0 |
py39-252D |
sha256:2bb16898c0c2816fe1787ea06945219069e4279b2c8ff3c5a252ee0e29193024 |
supported-252D |
sha256:a3a30be836c1c2f74502f6ce1b077a8f393bc3a13994199184c84734f4ea320e |
unsafe-252D |
sha256:b5643aaa4abdbbc814a470def110b454b035b119a4f8ccd21ad5f9ae425d1453 |
-
GitHub Action setup-python
- Supports all patch versions but does not support Python 2.7 and does not support free threaded 3.13 at the moment.
-
- Apt CPython 3.7 to 3.12 from deadsnakes PPA.
-
- pyenv CPython 3.8 to 3.12, PyPy 3.10.
-
- Lacks recent versions
- To file bug report or feature request, please create an issue.
- To report security vulnerability, please use GitHub Security Advisories.
- Want to contribute? Check Contribution Guidelines.
Check repository CHANGELOG.md