Skip to main content

Deploy Python Apps

Python is a beginner-friendly programming language popularly used for machine learning and other scientific projects. Python is served as an interpreted language, which means you don't need to compile your code before running it.

There's a default python interpreter from system but we recommend you to install it as your own through deployment scripts.

warning

Serving Python apps can be run using WSGI or via GLS. If you choose to run via GLS, you have to listen from given PORT env/args. If you choose to run it via WSGI, please note the default app name (that's passenger_wsgi.py) and the path of python interpreter to run with.

Example

The deployment script below installs the latest python compiler and writes app.py and serves that through WSGI bindings.

https://github.com/domcloud/recipes/blob/master/python.yml
source: clear
features:
- python latest
nginx:
root: public_html/public
passenger:
enabled: "on"
startup_file: app.py
app_type: python
python: .pyenv/shims/python
commands:
- filename: app.py
content: |
import platform

html_text = '''
<!DOCTYPE html>
<html>
<head>
<title>Python App</title>
<link rel="stylesheet" href="%s">
</head>
<body class="p-5 text-center">
<p><img src="%s" class="img-fluid rounded-circle"></p>
<h1 class="mb-3">Hello, world!</h1>
<p>Serving from Python version %s</p>
<p class="text-muted">DOM Cloud</p>
</body>
</html>
''' % (
'//unpkg.com/bootstrap/dist/css/bootstrap.min.css',
'//images.unsplash.com/photo-1465153690352-10c1b29577f8?fit=crop&w=200&h=200',
platform.python_version(),
)

def application(environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/html')]
start_response(status, response_headers)
return [html_text.encode('utf-8')]

Existing Python projects

For existing python apps, use the deployment script below. Note the WGSI file name (app.py). It's recommended to have requirements.txt so you don't have to install depedencies manually.

https://github.com/domcloud/recipes/blob/master/python-wsgi.yml
features:
- python latest
nginx:
root: public_html/public
passenger:
enabled: "on"
startup_file: app.py
app_type: python
python: .pyenv/shims/python
commands:
- test -f requirements.txt && pip install -r $_
https://github.com/domcloud/recipes/blob/master/python-uvicorn.yml
features:
- python latest
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: uvicorn main:app --port $PORT
commands:
- test -f requirements.txt && pip install -r $_ || pip install uvicorn

Other deployment scripts we offer also listed below.

The GLS binding is the basic for any custom web server either for Python and other code languages. The requirement to use this is your app must listen to given PORT env/args (either python ... --port=$PORT or env PORT=$PORT python ...)

https://github.com/domcloud/recipes/blob/master/python-gls.yml
features:
- python latest
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT python app.py
commands:
- test -f requirements.txt && pip install -r $_

Use other Python versions

To switch python version use feature syntax like python stable, python latest, python 3.8.1, python 3.8, etc. Check your current python version using python --version in SSH.

features:
- python 3.8.1

Python install scripts is powered by pyenv. Python binaries is provided by indygreg/python-build-standalone. When just mentioning python it's equivalent with python system which installing pyenv but still using system-wide python.

warning

The python binaries currently have issues that they don't have shared libraries which make venv or some legacy pip install broken. We advise to stick into python system until this is resolved.

However if you have to upgrade simply refer to version which there's no binary version (e.g. 3.11.0) to make pyenv compile the python binary, which is always works.

Installing depedencies

Installing python depedencies can be tricky and easily overlooked. We have system-wide installation of pip and pipenv. When python feature is installed, pyenv will be available to shim python and pip to your terminal profile. When changing python version using pyenv, the python interpreter will be installed to .pyenv/shims/python.

When installing with pipenv all depedencies are installed within a custom virtualenv. You shouldn't have to use python feature at all because pipenv already does it for you. To run the customized python and it's pip installation in NGINX use env PORT=$PORT pipenv run python app.py in app_start_command.

App Management

Your app do not restarted automatically after file changes. To restart, run restart via SSH.

Environment variables can be set either using NGINX's env_var_list or ~/.bashrc. Usually your language framework also reads .env files.

See NGINX and App Daemon for more information about NGINX and App managements including restarting, environment variables, and other global limitations.

App Logging

You can see app log from Check -> Check Process Logs tab. Only startup problems displayed in the browser.

Please use a proper logging mechanism such as the standard logging library then write it to a log file, or any other solution that suits you.

NGINX errors and traffic logs can be examined via Webmin or Check -> Check Process Logs tab.