--- Begin Message ---

I tested mod_wsgi and repoze.grok. My main goal is to use it to serve
a grokstar instance, but for now grokstar lack an auth functionnality,
so I can't use it right now.
For now I don't have a rest blog to post my feedback, so I've attached
it in .rst and the html generated.
I spend lots of hours reading mod_wsgi documentation, fixing errors
and writing this tutorial-like feedback. So I hope it will be useful!
You can modify, copy what have written and eventually update the grok
tutorial with it.

Oh and I didn't presented myself. I'm french, 22 years old. I just
finished my university studies in informatic. I begin working for real
next week in a young very small compagny doing Plone sites. I'll try
using some of grok techno with Plone. ;-)

Best regards
Vincent Fretin

This tutorial is a compilation of my experience and several documentation I read:

Installing mod_wsgi

Instructions to install mod_wsgi:

sudo apt-get install python2.4 python2.4-dev build-essential apache2
sudo apt-get install apache2-prefork-dev  # if you have apache2-mpm-prefork installed (default normally, you can verify with `dpkg -l|grep apache2`)
sudo apt-get install apache2-threaded-dev # if you have apache2-mpm-worker installed

Personnaly, I don't install setuptools with the python-setuptools package because it's not always the latest version. Download manually setuptools-0.6c8-py2.4.egg (or latest version, choose py2.4) at and execute the command:

sudo sh setuptools-0.6c8-py2.4.egg

Then install virtualenv:

sudo easy_install-2.4 virtualenv

Install mod_wsgi:

tar xzf mod_wsgi-2.1.tar.gz
cd mod_wsgi-2.1
./configure --with-python=/usr/bin/python2.4
sudo make install

Create a file /etc/apache2/mods-available/wsgi.load with in it:

LoadModule wsgi_module /usr/lib/apache2/modules/

Then activate the module with:

a2enmod wsgi

Note: a2enmod stands for "apache2 enable mod", this executable create the symlink for you. Actually a2enmod wsgi is equivalent to:

cd /etc/apache2/mods-enabled
ln -s ../mods-available/wsgi.load
ln -s ../mods-available/wsgi.conf # if it exists

Creating the sandbox

In the grok tutorial, the site is configured in mods-available/wsgi.conf. IMHO it's not a good idea, a file should be created in sites-available and activated with a2ensite command. We will go this way in the following.

Create a virtualenv (please replace ${sandbox} by a real path):

virtualenv --no-site-packages ${sandbox}
cd ${sandbox}
. bin/activate # at the end of this tutorial, type `deactivate` if you want to leave the virtual environment

Personnaly, I'll don't use --no-site-packages for repoze.plone for example to have the installed system-wide PIL package available. I never install eggs system-wide, except setuptools and virtualenv. I install PIL, PyXML and libxml2 with: apt-get install python-imaging python-xml python-libxml2.

Installing repoze.grok

repoze.grok 0.1.6 ships with grok 0.11, here we edit the to include grok 0.12.1:

easy_install -b . -e -i repoze.grok
cd repoze.grok
vi # set GROK_VERSION = '0.12.1'
vi setup.cfg # comment easy_install section
python develop
cd ..

Generate a grok instance:

mkgrokinstance .
cp etc/sample-users.zcml etc/users.zcml

and edit the password in etc/users.zcml

Copy the virtualhost site sample:

sudo cp etc/apache2.conf /etc/apache2/sites-available/grok

Note: in the etc/apache2.conf file included in the repoze.grok 0.1.6 package, PASTE_CONFIG should be grok.ini, not zope2.ini. Don't forget to correct it.

Configuration of the site in /etc/apache2/sites-available/grok


modify PASTE_CONFIG to look for grok.ini, not zope2.ini

Note on PYTHON_EGG_CACHE directory

simplejson-1.7.1-py2.4-linux-i686.egg was installed as a zipped egg, so when the application will be started, this egg will be automatically extracted in the PYTHON_EGG_CACHE, normally "~/.python-eggs". see sections:

  • "Access Rights Of Apache User"
  • "User HOME Environment Variable"

This directory depends of the HOME environment variable. The HOME apache user www-data is /var/www. You will get the error "[Errno 13] Permission denied: '/var/www/.python-eggs'" in your error.log apache file if you don't configure the user or python-eggs variable in the WSGIDaemonProcess directive. Tip: use tail -f /var/log/apache2/error.log in another console. Example: Please replace ${sandbox} by the path where you have created your sandbox, i.e your virtualenv directory. The file included in repoze.grok contains:

WSGIDaemonProcess grok threads=1 processes=1 maximum-requests=10000 python-path=${sandbox}/lib/python2.4/site-packages

The process belongs to www-data.www-data and python-eggs cache directory will be "/var/www/.python-eggs".

You can add python-eggs variable:

WSGIDaemonProcess grok threads=1 processes=1 maximum-requests=10000 python-path=${sandbox}/lib/python2.4/site-packages python-eggs=/tmp/python-eggs

The process belongs to www-data.www-data and python-eggs cache directory will be "/tmp/python-eggs".

Or you can specify user and group variable:

WSGIDaemonProcess grok user=${youruser} group=${youruser} threads=1 processes=1 maximum-requests=10000 python-path=${sandbox}/lib/python2.4/site-packages

The process belongs to youruser.youruser and python-eggs cache directory will be "/home/youruser/.python-eggs".

You can set both variables:

WSGIDaemonProcess grok user=${youruser} group=${youruser} threads=1 processes=1 maximum-requests=10000 python-path=${sandbox}/lib/python2.4/site-packages python-eggs=/tmp/python-eggs

The process belongs to youruser.youruser and python-eggs cache directory will be "/tmp/python-eggs".

Be careful, var/ directory and all files in it have to be writable by the user of the process. I use the third. It allows me to test with paster serve and mod_wsgi (not at the same time of course!) without changing var/ permissions.

Reload mechanism

"WSGIReloadMechanism Process" is the default for daemon mode when running mod_wsgi 2.0c5 or later. It was previously "WSGIReloadMechanism Module". Configure it explicitly doesn't hurt. For more details of the different reload mechanism, see: and in particular "Process Reloading Mechanism" section. "The way that the restart is performed does not affect the handling of the request, with it still being processed once the daemon process has been restarted." Cool, isn't it?

Final file

Here the file:

WSGIPythonHome ${sandbox}
WSGIDaemonProcess grok user=${youruser} group=${youruser} threads=1 processes=4 maximum-requests=10000 python-path=${sandbox}/lib/python2.4/site-packages
# python-eggs=/tmp/python-eggs
# please set processes=1 if you don't use a ZEO server!

<VirtualHost *:80>
  ServerName my.machine.local
  WSGIScriptAlias /site ${sandbox}/bin/grok.wsgi
  WSGIProcessGroup grok
  WSGIPassAuthorization On
  WSGIReloadMechanism Process
  SetEnv HTTP_X_VHM_HOST http://my.machine.local/site
  SetEnv PASTE_CONFIG ${sandbox}/etc/grok.ini

Launch the server

In developement

In developement, use paster serve:

bin/paster serve etc/grok.ini

To use auto-reload functionnality:

bin/paster serve --reload etc/grok.ini

In production

In production, use mod_wsgi.

If processes > 1 in the WSGIDaemonProcess directive, you have to use a ZEO server, start it before reloading apache2:

bin/zeoctl -C etc/zeo.conf start

And don't forget to configure your etc/zope.conf file to use the ZEO server.

The first time, enable your site and reload apache2:

a2ensite grok
/etc/init.d/apache2 reload

To stop your site:

a2dissite grok
/etc/init.d/apache2 reload

To reload your site:

touch ${sandbox]/bin/grok.wsgi

Note on restarting Apache2

I suppose that you have other applications configured with apache, maybe PHP applications, so we don't want to stop currently opened connections. If you want currently open connections not to be aborted, don't use 'apache2ctl restart' or 'apache2ctrl stop'. Use instead 'apache2ctl graceful' and 'apache2ctl graceful stop' respectively. See man apache2ctl for more details. Note on Ubuntu Hardy Heron, you can use this too:

/etc/init.d/apache2 reload
/etc/init.d/apache2 stop

Currently open connections are not aborted.


LockError: Couldn't lock '${sandbox}/var/Data.fs.lock'

If you have this error in your error.log apache file, it means you have more than one process trying to Lock your Data.fs. Please configure zope.conf to use ZEO server as the main storage or use processes=1 in the WSGIDaemonProcess directive. In production, the use of a ZEO server is recommended. Before starting apache2 (or enable site and reload apache2), issue the following command:

bin/zeoctl -C etc/zeo.conf start
#. daemon process started, pid=7538

But zeo dies and I don't know why. log/zeo.log gives me:

2008-07-28T15:32:06 INFO root daemon manager started
2008-07-28T15:32:06 INFO root spawned process pid=7525
2008-07-28T15:32:06 INFO root sleep 1 to avoid rapid restarts
2008-07-28T15:32:06 INFO root pid 7525: exit status 2; exiting now

For now I use no ZEO and only one process in the WSGIDaemonProcess directive.

Configuring a grok project

In grokproject 0.6, there was a --no-buildout to not execute zc.buildout after created the project. In grokproject 0.8, it was replaced by --run-buildout=no.

Create a new grok project:

easy_install -U grokproject # to be sure we have the latest version (here 0.8)
grokproject --run-buildout=no helloworld
cd helloworld
python2.4 develop # be careful, your virtual environment have to be activated to use the good python

helloworld/buildout.cfg and helloworld/ files will not be used.

Then create a ZCML slug, a file ${sandbox}/etc/grok-apps/helloworld-configure.zcml with only one line:

<include package="helloworld" />

To use an existing grok project, enter in your project, develop the egg and create a ZCML slug like above. For Grokstar I added <includeDependencies package="." /> after <include package="grok" /> in the configure.zcml. You don't use the buildout.cfg of grokstar here, but if your use it and have added includeDependencies, you should remove from buildout.cfg the following lines:

<include package="zope.sendmail" file="meta.zcml" />
<include package="zope.sendmail" />

Attachment: wsgi.rst
Description: Binary data

Grok-dev mailing list

--- End Message ---
Repoze-dev mailing list

Reply via email to