I’m seeing the topic that how to run MoinMoin wiki with Nginx is still active in the Nginx (Russian) mailing list and some other places, and the post “Standalone MoinMoin Wiki with Nginx Proxy” I wrote about 2 years ago has a high ranking in Google search engine. So I decide to give an update on this topic according to my recent experience.
I’v switched MoinMoin version from 1.8 to 1.9, and the running method from standalone to fastcgi.
As of 1.9.3 released a few days ago, MoinMoin has a bunch of changes. For those who wanna upgrade from 1.8 to 1.9, here’s some advise:
- Read the changelog, linked above. Pay attention the “HINT”s.
- Get to know the requirements by MoinMoin.
- Read the doc on updating MoinMoin.
- Do exactly as the docs say, especially, watch out for your data, BACKUP can save your life.
- Follow the above four points.
I’m running MoinMoin 1.9.3 currently. Taken as a whole, it looks like below:
Client ----> Nginx Web Frontend -----------+
| fastcgi_pass
\|/
+-------------------------+
moin.fcgi | spawn-fcgi-moin.socket |
spawn-fcgi ---------------> | or |
| localhost:port |
+-------------------------+
Configuration snip in Nginx:
rewrite ^/moin_static[0-9]+/(.*)$ /moin/$1 last;
location /wiki {
if ($uri ~ ^/wiki(.*)?) {
set $wiki_url $1;
}
if (!-f $request_filename) {
fastcgi_pass unix:/var/run/spawn-fcgi-moin.socket;
}
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $wiki_url;
#fastcgi_param SCRIPT_NAME /wiki; # <-- This can be removed, see below.
}
$ grep -v '^[[:space:]]*#' moin.fcgi
"""
MoinMoin - CGI/FCGI Driver script
@copyright: 2000-2005 by Juergen Hermann <jh@web.de>,
2008 by MoinMoin:ThomasWaldmann,
2008 by MoinMoin:FlorianKrupicka,
2010 by MoinMoin:RadomirDopieralski
@license: GNU GPL, see COPYING for details.
"""
import sys, os
sys.path.insert(0, '/usr/lib64/python2.6/site-packages')
sys.path.insert(0, '/path/to/wikiconfigdir')
from MoinMoin import log
log.load_config('/path/to/logfile')
logging = log.getLogger(__name__)
from MoinMoin.web.serving import make_application
app = make_application(shared=True) # <-- adapt here as needed
fix_script_name = '/wiki' # <-- adapt here as needed
if fix_script_name is None:
application = app
else:
def script_name_fixer(env, start):
env['SCRIPT_NAME'] = fix_script_name
return app(env, start)
application = script_name_fixer
fix_apache_win32 = False # <-- adapt here as needed
if fix_apache_win32:
from werkzeug.contrib.fixers import PathInfoFromRequestUriFix
application = PathInfoFromRequestUriFix(application)
try:
from flup.server.fcgi import WSGIServer
except ImportError:
logging.warning("No flup-package installed, only basic CGI support is available.")
from MoinMoin.web._fallback_cgi import WSGIServer
WSGIServer(application).run()
The fix_script_name is very useful. With this setting, neither
proxy_set_header X-Moin-Location /wiki/;
nor
fastcgi_param SCRIPT_NAME /wiki;
is no longer needed in Nginx If you're running MoinMoin at http://domain/wiki/.
BTW, FYR: MoinMoin Wiki FCGI control script for Slackware Linux
$ cat rc.spawn-fcgi-moin
#!/bin/sh
#
# MoinMoin Wiki FCGI control script for Slackware Linux
#
# Copyright (c) 2008-2010 Cowyn Li <cowynli_#_gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
SPAWNFCGI="/usr/bin/spawn-fcgi"
SPAWNAPP="/path/to/moin.fcgi"
APPNAME="Moin"
IP="127.0.0.1"
PORT="9001"
SPAWNUNIXSOCKET="/var/run/spawn-fcgi-moin.socket"
FORKCHILDREN="1"
MAXCGIREQUEST="1024"
PID="/var/run/spawn-fcgi-moin.pid"
SPAWNCHROOT=
USER="apache"
GROUP="apache"
UNIXSOCKETUSER="apache"
UNIXSOCKETGROUP="apache"
if [ ! -z ${SPAWNCHROOT} ]; then
SPAWNOPTS="-c ${SPAWNCHROOT} -S"
fi
start_cmd() {
PHP_FCGI_CHILDREN=${FORKCHILDREN} \
PHP_FCGI_MAX_REQUESTS=${MAXCGIREQUEST} \
${SPAWNFCGI} -f ${SPAWNAPP} -P ${PID} -u ${USER} -g ${GROUP} \
$*
}
spawn_start() {
if [ ! -x ${SPAWNFCGI} ]; then
echo "Can not execute spawn-fcgi, exiting ..."
exit 1
fi
if [ ! -x ${SPAWNAPP} ]; then
echo "Can not execute ${APPNAME} FCGI, exiting ..."
exit 1
fi
if [ -s ${PID} ]; then
echo "${APPNAME} FCGI is already running?"
exit 1
fi
echo "Starting ${APPNAME} FCGI ..."
case "$2" in
unixsocket)
start_cmd -s ${SPAWNUNIXSOCKET} -U ${UNIXSOCKETUSER} -G ${UNIXSOCKETGROUP} ${SPAWNOPTS}
;;
ip|'')
start_cmd -a ${IP} -p ${PORT} ${SPAWNOPTS}
;;
*)
spawn_usage
esac
}
spawn_stop() {
if [ ! -f ${PID} ]; then
echo "No ${APPNAME} FCGI process found, exiting ..."
else
echo "Stopping ${APPNAME} FCGI ..."
kill -QUIT $(cat ${PID})
if [ -f ${PID} ]; then
/bin/rm -f ${PID}
fi
if [ -S ${SPAWNUNIXSOCKET} ]; then
/bin/rm -f ${SPAWNUNIXSOCKET}
fi
fi
}
spawn_restart() {
spawn_stop
sleep 3
spawn_start $*
}
spawn_usage() {
echo "usage: $0 <start|stop|restart> [ip(default)|unixsocket]"
}
case "$1" in
start)
spawn_start $*
;;
stop)
spawn_stop
;;
restart)
spawn_restart $*
;;
*)
spawn_usage
esac
Anyway, this scenario is a just work usage. As MoinMoin is now a WSGI server, and using flup as the middleware for communication.
All these stuff is making things more complex.
BTW, flup author said that he didn't use flup himself anymore 2+ years ago. I've no idea how is it now.
The simplest way is just to use "standalone" wikiserver.py bundled with MoinMoin, if you don't care about scalability and etc.. That also makes your life darker, LOL.

