Mezzanine with mod_wsgi in virtualenv on apache (on Gentoo)

(11 comments)

So .. since this page/blog is running on Mezzanine I thought I'd share what I had to do to get it to work.

First off I did this on Gentoo, but in general stuff should apply to most other distributions anyway.

Versions I used:

  • Apache 2.4.27
  • python 3.6.3
  • mod_wsgi 4.5.13
  • postgresql 9.4

Don't forget to enable apache loading mod_wsgi (on Gentoo add "-D WSGI " to APACHE2_OPTS in /etc/conf.d/apache).

I am running Mezzanine on it's own virtualhost.

For the rest of this I go with the assumption that the above is installed and configured correctly.

Quick & dirty Mezzanine install:

python3.6 -m venv myenv
source myenv/bin/activate
pip install mezzanine south psycopg2

Of course replace psycopg2 with whatever Database driver you intend to use.

Here is what I installed (pip freeze output):

beautifulsoup4==4.6.0
bleach==2.1.2
certifi==2018.1.18
chardet==3.0.4
Django==1.10.8
django-contrib-comments==1.8.0
filebrowser-safe==0.4.7
future==0.16.0
grappelli-safe==0.4.7
html5lib==1.0.1
idna==2.6
Mezzanine==4.2.3
oauthlib==2.0.6
Pillow==5.0.0
psycopg2==2.7.4
pytz==2018.3
requests==2.18.4
requests-oauthlib==0.8.0
six==1.11.0
South==1.0.2
tzlocal==1.5.1
urllib3==1.22
webencodings==0.5.1

Then create your project:

mezzanine-project <projectname>

Then edit your <project>/local_settings.py to use the correct database settings - and don't forget to set ALLOWED_HOSTS (like I did at first).

chmod +x <project>/manage.py
./<project>/manage.py createdb

This should create the DB, superuser, .. then I ran

./<project>/manage.py collectstatic

you can test it with

./<project>/manage.py runserver 

If you need to change the ip/port:

./<project>/manage.py runserver <ip>:<port>

Make sure stuff works ok, set up what you want to setup first or do your development.

For deploying with mod_wsgi .. here's a snippet from my apache config (I run it on https *only* and just redirect http to the https version):

<VirtualHost <your_ip>:443>
ServerName your.domain.name
ServerAdmin your_email@your_domain
ErrorLog /path/to/your/logs/your.domain.name_error.log
CustomLog /path/to/your/logs/your.domain.name_access.log combined

LogLevel Info

SSLCertificateFile /path/to/your/sslcerts/cert.pem
SSLCertificateKeyFile /path/to/your/sslcerts/privkey.pem
SSLCertificateChainFile /path/to/your/sslcerts/fullchain.pem

WSGIDaemonProcess lvmezz home=/path/to/your/MezzanineInstallMezzanine/myenv processes=1 threads=15 display-name=[wsgi-lvmezz]httpd python-path=/path/to/your/MezzanineInstallMezzanine/mezzproject:/path/to/your/MezzanineInstallMezzanine/myenv/lib64/python3.6/site-packages

WSGIProcessGroup lvmezz
WSGIApplicationGroup %{GLOBAL}

WSGIScriptAlias / /path/to/your/MezzanineInstallMezzanine/mezzproject/apache.wsgi
Alias /static /path/to/your/MezzanineInstallMezzanine/mezzproject/static
Alias /robots.txt /path/to/your/MezzanineInstallMezzanine/htdocs_static/robots.txt
Alias /favicon.ico /path/to/your/MezzanineInstallMezzanine/htdocs_static/favicon.ico

<Directory /path/to/your/MezzanineInstallMezzanine/mezzproject>
  Options -Indexes +FollowSymLinks +MultiViews
  php_flag engine off
  <IfModule mod_authz_host.c>
    Require all granted
  </IfModule>
</Directory>

<Directory /path/to/your/MezzanineInstallMezzanine/mezzproject/static>
   Options -Indexes +FollowSymLinks +MultiViews -ExecCGI
   php_flag engine off
   RemoveHandler .cgi .php .php3 .php4 .phtml .pl .py .pyc .pyo
   AllowOverride None
   <IfModule mod_authz_host.c>
      Require all granted
   </IfModule>
</Directory>

</VirtualHost>

Should all be pretty self explainatory (maybe I'll elaborate at a later point, but I don't have that much time now and I'd rather get it finished).

Here's the apache.wsgi file:

from __future__ import unicode_literals
import os, sys, site

site.addsitedir('/path/to/your/MezzanineInstall/myenv/lib64/python3.6/site-packages')
activate_this = os.path.expanduser('/path/to/your/MezzanineInstall/myenv/bin/activate_this.py')
exec(open(activate_this, 'r').read(), dict(__file__=activate_this))

PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(PROJECT_ROOT, ".."))
settings_module = "%s.settings" % PROJECT_ROOT.split(os.sep)[-1]
os.environ["DJANGO_SETTINGS_MODULE"] = settings_module

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

I found activate_this.py at https://github.com/pypa/virtualenv/blob/master/virtualenv_embedded/activate_this.py (since with python3 execfile wasn't really working for me):

"""By using execfile(this_file, dict(__file__=this_file)) you will
activate this virtualenv environment.
This can be used when you must use an existing Python interpreter, not
the virtualenv bin/python
"""

try:
    __file__
except NameError:
    raise AssertionError(
        "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
import sys
import os

old_os_path = os.environ.get('PATH', '')
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if sys.platform == 'win32':
    site_packages = os.path.join(base, 'Lib', 'site-packages')
else:
    site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = base
# Move the added items to the front of the path:
new_sys_path = []
for item in list(sys.path):
    if item not in prev_sys_path:
        new_sys_path.append(item)
        sys.path.remove(item)
sys.path[:0] = new_sys_path

that would be the Apache + mod_wsgi config (make sure to replace the python version number if you don'T use 3.6)

Make sure that apache has the correct permissions to all the files too btw ;)

Currently unrated

Comments

Comment deleted 2 months, 1 week ago

Comment deleted 2 months, 1 week ago

Comment deleted 2 months, 1 week ago

Comment deleted 2 months, 1 week ago

Comment deleted 2 months, 1 week ago

Comment deleted 2 months, 1 week ago

Comment deleted 2 months ago

Comment deleted 2 months ago

Comment deleted 2 months ago

Comment deleted 2 months ago

Comment deleted 2 months ago

New Comment

required

required (not published)

optional

required