Python in virtualmin

SYSTEM INFORMATION
OS type and version Debian Linux 12
Usermin version 2.203
Virtualmin version 7.30.8
Theme version 23.03
Apache version 2.4.62
Package updates All installed packages are up to date

I have a client who already has a VS on a VM and now wants to upload a Python App. I have no experience of this (or to be honest of very much Python).

He has already told me that it ((the App) uses Python v 3.13.4 where as the OS has installed v 3.11.2

Is there anything special to do (on the VS) to accommodate?

The OS python version most likely will stay the same
For instance on my Rocky Linux OS 9.6 is it still 3.9.XX (3.9.21) .
I have installed a few other versions of Python , such as 3.12.x and 3.13.x, I just use the proper interpreter path at the shebang line.

Your client can install newer versions of Python to use but the default the OS uses will remain the same.

It’s not “in Virtualmin”. Web applications don’t run in Virtualmin.

You can generally follow the documentation for the application you are wanting to run. Usually, it will involve running it under an app server like unicorn, gunicorn, uvicorn, etc. and proxying to it from your web server, whether that’s Apache on nginx (most web apps provide documentation for both).

Virtualmin does nothing unusual that would prevent most web application documentation from being relevant and applicable.

Installing a different Python version can be done in a variety of ways. For development or one-off web applications, I have recently begun using uv for this problem. I install a local (to my user) Python version and create a virtualenv (also local to my user) so I can have exactly the version of Python and versions of libraries I need for my applications. uv

But, there are many ways to do it. Python has a cacophony of packaging and installation options, all terrible and incompatible in various ways. uv is the least terrible I have found thus far.

You may also find your OS (which you have kept secret from us, which prevents specific suggestions) has options for installing other Python versions. e.g. the deadsnakes project for Ubuntu: deadsnakes · GitHub

I use the latter for production, I always use native system packages, so deadsnakes is where I get my Python versions (for my day job, where I am required to use Ubuntu and Python). I still build a virtualenv for each application, because the Python community hates backward compatibility and has seemingly intentionally user-hostile deprecation and versioning practices that result in minor version changes in libraries or tools causing cascading dependency hell or breakages. So, the only sane way to handle it is to rebuild the whole virtualenv with some tool (uv, pipenv, poetry, in order of least horrifying to most horrifying).

Note that you can use tools like uv, pipenv, poetry, and virtualenv, without root privileges, so domain owner users can do this all by themselves, with no administrator assistance, assuming they have ssh access and aren’t in a restrictive jail. They can also start application servers (we also have a module for creating init services for non-root users, so they can start app servers on boot…I’m not sure if that module is installed by default, though, I think it’s just called virtualmin-init). And proxy rules can be created by non-privileged users, though some applications require something more complicated than the Proxy Paths Virtualmin feature can create and that might need some root assistance.

3 Likes

Thanks, that is what I thought/hoped. at the moment the VS has only his domains and being definitely development and not production so I would rather leave most server-side work up to him.

Sorry about that, (I have edited the OP with the details - I did not get the usual prompt in this category so was neglectful :flushed_face:

Your comments above will be very helpful and has opened up a great deal of further reading - I’m not sure I really want to go down that worm-hole - initially I will just post it back to the client so he can come back with more specific questions. (I just don’t need to learn yet another language this late in life)

hey @Stegan as mentioned by Joe, its os specific - and also I would join him thats not question of virtualmin - it does not even manage this things. I thing you did stepped into those every days worm-work-holes - if your client can install custom py do it for them if not - decline the ticket - end of the day they will be limited what os is supplying to them or they will have to install custom repos which it might turn os to zombie os. Generally this is not managed by virtualmin at all

That’s not correct. If the user has a regular shell (bash or whatever, and not jailed) and sufficient disk space, they can install whatever Python version and libraries they need using any of a variety of tools, and they won’t have any impact on the system Python or libraries.

If you jail your domain owner users, they certainly won’t have the necessary tools to do so, unless you add a bunch of stuff to the jail (what stuff, I don’t know…certainly curl and a bunch of Python tools and libraries…uv is available as a statically linked binary and may be able to do most stuff without a bunch of dependencies, though). You’ll need to experiment.

Since the app requires Python 3.13.4 but the system has 3.11.2, would it be better to install the required version globally, or would setting up a virtual environment with tools like pyenv or venv inside the VS be a safer and more manageable approach?

Absolutely not! I cannot be more emphatic. That’s a disaster waiting to happen. Your OS has a bunch of Python scripts doing vital stuff, and because the Python ecosystem is overtly hostile to maintaining broad compatibility across minor versions of Python and libraries, if you try to replace the global Python version and libraries, you’re extremely likely to end up with a pile of smoking wreckage.

Just do what I recommended. My day job is exactly this. I’m responsible for packaging and deploying hundreds of thousands of lines of Python code across three major OS versions, across two architectures, on devices that are difficult/expensive to get physical access to. I’m not just guessing here.

The only sane thing to do with Python applications is give them their own virtual environment with all their own libraries, the exact versions they want. You’ll quickly find out how specific dependencies are (in the sense of what actually works together), and how poorly specified they are (in terms of how their dependencies are specified in documentation and pyproject.toml or whatever), if you try to maintain a global installation of Python and libraries that works across a broad spectrum of applications.

Let the system Python be the system Python. Setup your own version for each app that needs a special version. Not all Python apps are picky, but many are, and sometimes it’s the core libraries and applications that are picky and break at the drop of a hat (e.g. setuptools, virtualenv, pip, pipenv, etc.).

There’s a reason the tools exist to make little Python fiefdoms for your apps. It is painful to try to use one global Python installation across a bunch of applications of varying ages and development stages.

There used to be a strongly held principle of not breaking stuff in various programming language ecosystems. That principle is broken now (Perl remains steadfast and trustworthy, mostly, in this regard, Python and Node.js are actively hostile to stability/compatibility, and PHP is somewhere in between), and you’re not going to have a nice time trying to use new stuff on old versions or vice versa, when it comes to the libraries your apps depend on.

1 Like

Though I guess I should mention if you’re running the same app with all the same deps/versions, you could install an additional global version on a different binary name using, e.g. deadsnakes packages. Not an upgrade, just another package with a different name and different paths for the binaries and libs.

That is a reasonable thing to do, as it does not replace the system Python, you can still use it in virtualenvs (for your specific libs), etc. You just call python313, or whatever instead of python3. This is actually what I do on my deployments…because I’m always deploying the same stack of things built against the specific Python versions we have broadly installed. The apps still run in a virtualenv, one per app, but the Python binary is global. Users can’t control that, though, while a local install can be managed by a domain owner.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.