.. -*- coding: utf-8; mode: rst -*- .. include:: ../apache_setup_refs.txt .. _xref_site_pyapps: ================================================================================ WSGI Anwendungen ================================================================================ Es wird eine Konfiguration eingerichtet, über welche es möglich ist WSGI (Python) Anwendungen zu betreiben. Eine kleines *HelloWorld* Beispiel wird ebenfalls mit installiert. Installation ============ .. code-block:: bash $ ${SCRIPT_FOLDER}/apache_setup.sh installWSGI Mit dem Kommando ``installWSGI`` werden die folgenden Schritte ausgeführt. * Es wird `Apache mod_wsgi`_ installiert (`mod_wsgi RTD`_) * Es wird der Ordner ``/var/www/pyApps`` eingerichtet, in dem Python WSGI Anwendungen abgelegt werden können. .. code-block:: bash $ apt-get install libapache2-mod-wsgi-py3 python-imaging virtualenv $ cd /etc/apache2/mods-available/ $ sudo -H mv wsgi.conf wsgi.conf-disabled $ sudo -H mkdir /var/www/pyApps * Es wird eine virtuelle Python Umgebung (``pyenv``) in dem Ordner ``/var/www/pyApps`` eingerichtet. * In die virtuelle Python Umgebung werden (via pip) verschiedene Python Module vorinstalliert (sollte nicht ohne weiteres ins Internet gestellt werden). .. code-block:: bash $ cd /var/www/pyApps $ sudo -H virtualenv "pyenv" --prompt="pyenv" $ cd /var/www/pyApps/pyenv $ source bin/activate $ pip completion --bash | sudo -H tee /etc/bash_completion.d/pip > /dev/null $ pip install docutils Jinja2 Pygments Sphinx Flask Werkzeug pylint \ pyratemp pyudev psutil sqlalchemy babel simplejson $ sudo -H a2ensite py-apps $ sudo -H service apache2 reload * Es wird eine Test-Seite ( https://localhost/hello.py ) eingrichtet. .. code-block:: bash $ sudo -H ap2ensite hello_py $ sudo -H service apache2 reload De-Installation =============== .. code-block:: bash $ ${SCRIPT_FOLDER}/apache_setup.sh deinstallWSGI Anmerkungen =========== Das WSGI-Modul war mal ein Projekt auf google-code, ein paar Sachen kann man immernoch dort nachlesen z.B. * Simplified GIL State: https://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API Inzwischen wird das WSGI-Modul auf github gehostet und weiterentwickelt. In dem Github Projekt wird auch vieles aufgeräumt: * Eine aktuelle Doku gibt es bei *Read The Docs* `mod_wsgi RTD`_ * Das Reposetory bei github ist `Apache mod_wsgi`_ * Hardening Aspekte ???? .. _xref_site_py_apps_conf: py-apps.conf ============ Die folgende ``py-apps.conf`` Site, richtet eine Umgebung ein, in der WSGI-Anwendungen betrieben werden können. Die Python-Prozesse laufen in einer virtuellen-Python Umgebung, die über die Direktive ``WSGIPythonHome`` gesetzt wird. Es wird mit der Direktive ``WSGIDaemonProcess`` die Prozessgruppe ``pyApps`` eingerichtet. Die ``WSGI....`` Direktieven sind in der `mod_wsgi RTD Konfiguration`_ beschrieben. .. code-block:: apache # Die Prozesse laufen in einer VirtualEnv Umgebung WSGIPythonHome /var/www/pyApps/pyenv # Die Prozessgruppe pyApps für diese Python-Anwendungen WSGIDaemonProcess pyApps \ user=www-data group=nogroup \ processes=2 threads=5 maximum-requests=5 ... In der Konfiguration wird eine Prozessgruppe ``pyApps`` eingerichtet, deren Prozesse unter dem Apache-Account ``www-data`` (und ``nogroup``) laufen. Diese Prozessgruppe ``pyApps`` wird nun in der Resource ``/var/www/pyApps`` genutzt. .. code-block:: apache ... WSGIProcessGroup pyApps WSGIApplicationGroup %{GLOBAL} .. todo:: Da ich nicht davon ausgehen kann, dass alle Python Module die eine WSGI Anwendungen nutzt auch Thread-safty sind setze ich meine WSGI Anwendungen immer in die `WSGIApplicationGroup`_ ``%{GLOBAL}``. Nähers zu dem Thema gibt der Beitrag `Python Simplified GIL State API`_. Ich bin allerdings auch immer etwas verunsichert, weil mir nicht ganz klar ist, wie die Anordnung der Prozesse und Threads bei ``%{GLOBAL}`` nun genau ist (hängt vermutlich auch von anderen Faktoren ab?) und ob es Sinn macht bei ``%{GLOBAL}`` mehr als einen Thread zu definieren. WSGI-Test Anwendung =================== Die Test-Site sollte nur in einer Entwickler-Umgebung installiert werden. Sie besteht aus nur einer Datei ``/var/www/pyApps/helloWorld/index.wsgi``. .. code-block:: python import os, sys, urlparse, traceback, pprint, urlparse, pwd def application(environ, start_response): status = '200 OK' o = 'WSGI: It works! :-)' try: o += '\nprocess id: ' + str(os.getpid()) o += '\nparent process: ' + str(os.getppid()) o += '\nuser/group: ' + "%s/%s (%s/%s)" % (os.getuid(), os.getgid(), os.geteuid(), os.getegid()) o += '\npwd user: ' + pprint.pformat(pwd.getpwuid(os.getuid())) ...o += '\nWSGI environment:\n' + pprint.pformat(environ, indent=4) o += '\nQuery String:\n' + pprint.pformat(urlparse.parse_qs(environ['QUERY_STRING']), indent=4) ...o += '\nPython version: ' + pprint.pformat(sys.version) ... except: o += "\n\n" + traceback.format_exc() response_headers = [ ( 'Content-type', 'text/plain') , ( 'Content-Length', str(len(o))) ] start_response(status, response_headers) return [o] Die Installation erfolgte in den ``/var/www/pyApps`` Ordner. Für den bereits oben in der ``py-apps.conf`` die virtuelle Python Umgebung ``WSGIPythonHome /var/www/pyApps/pyenv`` und die ``WSGIDaemonProcess pyApps`` definiert wurden. Die ``hello_py`` Site definiert nur noch den Alias, damit die Site unter der URL https://localhost/hello.py angeboten wird. .. code-block:: apache WSGIScriptAlias /hello.py /var/www/pyApps/helloWorld/index.wsgi