Run mod_wsgi with virtualenv or Python with version different that system default

13,843

Solution 1

You have to add the following line in your apache.conf in order to give the right executable and the path to the virtualenv.

WSGIPythonHome /usr/local/bin
WSGIPythonPath /home/fenikso/virtualenv/lib/python3.4/site-packages

You will find all the options of these two command in the mod_wsgi documentation

Be aware that you must have the version of mod_wsgi compatible with the python executable. In your case, you probably have to install mod_wsgi3.4 and configure apache to use it instead of the standart mod_wsgi module.

The whole configuration file should be :

WSGIPythonHome "/usr/local/bin"
WSGIPythonPath "/home/fenikso/virtualenv/lib/python3.4/site-packages"

<VirtualHost *:80>
        ServerName album2.site.cz
        Alias /static "/home/fenikso/Album/static"
        Alias /photos "/home/fenikso/Album/photos"
        Alias /thumbs "/home/fenikso/Album/thumbs"
        WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
        <Directory "/home/fenikso/Album">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/static">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/photos">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/thumbs">
            AllowOverride None
            Allow from all
        </Directory>
</VirtualHost>

Solution 2

Look into the WSGIPythonHome and WSGIPythonPath directives. It's also possible that you have a python2.6 mod_wsgi installed, mod_wsgi must be compiled for the intended python version and does not support multiple python versions. So check that your mod_wsgi is py3.4 compatible and set the directives above.

Alternatively, you could run the flask app with a python server like gunicorn and proxypass from apache to gunicorn.

Share:
13,843
Fenikso
Author by

Fenikso

#SOreadytohelp

Updated on June 13, 2022

Comments

  • Fenikso
    Fenikso almost 2 years

    I am trying to make my Flask application work on CentOS server. Basically the issue is that I have Python 2.6 installed in /usr/bin which is system default and Python 3.4 installed in /usr/local/bin. I would like to use Python 3.4 virtualenv or at least Python 3.4 interpreter for mod_wsgi to run my application.

    I have created virtualenv in ~/virtualenvs/flask.

    I have this WSGI script:

    import os
    import sys
    from logging import Formatter, FileHandler
    
    APP_HOME = r"/home/fenikso/Album"
    
    
    activate_this = os.path.join("/home/fenikso/virtualenvs/flask/bin/activate_this.py")
    execfile(activate_this, dict(__file__=activate_this))
    
    sys.path.insert(0, APP_HOME)
    os.chdir(APP_HOME)
    
    from app import app
    
    handler = FileHandler("app.log")
    handler.setFormatter(Formatter("[%(asctime)s | %(levelname)s] %(message)s"))
    app.logger.addHandler(handler)
    application = app
    

    And following config in Apache:

    <VirtualHost *:80>
            ServerName album2.site.cz
            Alias /static "/home/fenikso/Album/static"
            Alias /photos "/home/fenikso/Album/photos"
            Alias /thumbs "/home/fenikso/Album/thumbs"
            WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
            <Directory "/home/fenikso/Album">
                AllowOverride None
                Allow from all
            </Directory>
            <Directory "/home/fenikso/Album/static">
                AllowOverride None
                Allow from all
            </Directory>
            <Directory "/home/fenikso/Album/photos">
                AllowOverride None
                Allow from all
            </Directory>
            <Directory "/home/fenikso/Album/thumbs">
                AllowOverride None
                Allow from all
            </Directory>
    </VirtualHost>
    

    However, when trying to run the application, I get an error:

    Apache/2.2.15 (Unix) DAV/2 mod_wsgi/3.2 Python/2.6.6 mod_fcgid/2.3.7 PHP/5.3.3 mod_ssl/2.2.15 OpenSSL/1.0.1e-fips SVN/1.6.11 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations
    mod_wsgi (pid=14627): Target WSGI script '/home/fenikso/Album/wsgi.py' cannot be loaded as Python module.
    mod_wsgi (pid=14627): Exception occurred processing WSGI script '/home/fenikso/Album/wsgi.py'.
    Traceback (most recent call last):
       File "/home/fenikso/Album/wsgi.py", line 15, in <module>
         from app import app
       File "/home/fenikso/Album/app.py", line 1, in <module>
         from flask import Flask
     ImportError: No module named flask
    

    I have noticed that either Python 2.6 is being ran and my virtualenv is not activated. What would be the proper way to get this working and still have the Python 2.6 as a system default?

  • Fenikso
    Fenikso over 9 years
    Thanks for the suggestion. I tried to look into WSGIPythonHome and WSGIPythonPath, but I have no idea how to use them correctly as I have not found any examples. Also, how do I check mod_wsgi "type"? I just did yum install mod_wsgi.
  • kalhartt
    kalhartt over 9 years
    @Fenikso , @afrancais has a more complete example of using the directives, see his answer. You can check which python mod_wsgi is compiled for by doing ldd on the lib, probably ldd /usr/{lib,lib64}/httpd/modules/mod_wsgi.so
  • Fenikso
    Fenikso over 9 years
    I think this is the right way. However I was not able to make it work in my environment. Too many things broken and messy, so I gave up and tried another way.
  • Fenikso
    Fenikso over 9 years
    However, should not the WSGIPythonHome and WSGIPythonPath be outside <VirtualHost>?
  • Fenikso
    Fenikso over 9 years
    Thanks for the valuable information about ldd and suggesting Gunicorn. In the end I went with uWSGI + Nginx. Helpful was that uWSGI can be installed with pip, so I could install it directly for required Python version.
  • afrancais
    afrancais over 9 years
    You are quite right, these options must be outside the <VirtualHost> block. My mistake. If you have to use a different virtualenv for each <VirtualHost>, you may use the WSGIDaemonProcess and WSGIProcessGroup directives, by setting the python-path option.