Version 4 (modified by 12 years ago) ( diff ) | ,
---|
Running Trac with Gunicorn
Gunicorn (Green Unicorn) is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model ported from Ruby's Unicorn project. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.
- Install gunicorn
Gunicorn is a python project which lives on pypi, so we can use easy_install or pip to install gunicorn :
$> pip install gunicorn
I prefer to use a virtualenv (http://pypi.python.org/pypi/virtualenv), to not have to install gunicorn in a system wide fashion.
- Write your wsgi file
Gunicorn is WSGI compliant, so we need a simple python script that work as an entry point:
import sys import os sys.stdout = sys.stderr #put here your ENV's Variables # here is an example with multiple instances os.environ['TRAC_ENV_PARENT_DIR'] = '/home/repos/trac/' os.environ['PYTHON_EGG_CACHE'] = '/home/repos/projects/.eggs/' import trac.web.main application = trac.web.main.dispatch_request
Now, we will test it:
$> gunicorn -w2 tracwsgi:application -b 0.0.0.0:8000 2011-03-04 13:21:10 [14900] [INFO] Starting gunicorn 0.12.0 2011-03-04 13:21:10 [14900] [INFO] Listening at: http://127.0.0.1:8000 (14900) 2011-03-04 13:21:10 [14901] [INFO] Booting worker with pid: 14901 2011-03-04 13:21:10 [14902] [INFO] Booting worker with pid: 14902
Now, launch your web browser, and go to http://yourip:8000 and it should work. How it works: gunicorn is looking for a method called "application" in the tracwsgi.py file
- Configure Nginx
So, now we have Gunicorn running, but we will make it works with nginx which will redirect tracs requests to gunicorn:
upstream trac_gunicorn { server unix:///home/repos/projects/run/trac.sock; } server { listen 80; server_name trac.example.com; access_log /var/log/nginx/trac.access.log; error_log /var/log/nginx/trac.error.log info; include "/etc/nginx/acl.conf"; location / { auth_basic "Secure Login"; auth_basic_user_file /etc/nginx/conf/users; proxy_pass http://trac_gunicorn; } location ~ /(.*?)/chrome/site/ { rewrite /(.*?)/chrome/site/(.*) /$1/htdocs/$2 break; root /home/repos/trac.enabled; } }
Note: Nginx will redirect request to a unix socket. It can be a simple ip:port combination. It can be a multiple instance of gunicorn. Take a look in the nginx documentation : http://wiki.nginx.org/HttpUpstreamModule
To add a basic or digest authentication, you'll have to provide a file as in the example above, created using htpasswd file. To make gunicorn listen on a unix socket, add this option :
gunicorn -w2 -b unix:///home/repos/projects/run/trac.sock tracwsgi:application
Note: It seems the wsgi entry point does not handle the Digest or Basic http authentication. To ensure the authentication middleware are passed, you'll have to hack a little bit the tracwsgi.py :
import sys import os sys.stdout = sys.stderr os.environ['TRAC_ENV_PARENT_DIR'] = '/home/repos/trac.enabled/' os.environ['PYTHON_EGG_CACHE'] = '/home/repos/projects/.eggs/' from trac.web.standalone import AuthenticationMiddleware from trac.web.main import dispatch_request from trac.web.auth import BasicAuthentication def application(environ, start_application): auth = {"*" : BasicAuthentication("/etc/nginx/conf/users", "realm")} wsgi_app = AuthenticationMiddleware(dispatch_request, auth) return wsgi_app(environ, start_application)