There are many tutorial/procedures on this topic, I just wish to add a few notes on the pieces I’ve found more obscure and difficult to setup.

I’m running a VM on slicehost and I haven’t already found the resources to perform a full upgrade to something newer than the original Ubuntu Hardy which was installed at setup time.

[2014] Yet another update: the problem can be solved setting the environment var directly in the wsgi python script:

"""
WSGI config for djprj project.

This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.

Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.

"""
import os

import sys
sys.path.append(os.path.dirname(__file__))

os.environ['LC_ALL']="it_IT.UTF-8"

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


 

Update: with latest  ubuntu 12.04 I didn’t have to do anything special to support UTF-8, everythig worked out of the box.

Update2: recently UnicodeEncodeError popped up again, it turned out that  I had restarted uwsgi from the root account which had LC_ALL = POSIX instead of UTF-8, restarting the service with sudo from another account which has LC_ALL=’en_US.UTF-8 was ok (if someone has an explanation for that, please let me know).

 

Basically, I’ve compiled latest nginx from sources (older versions did not support uwsgi natively) and installed uwsgi with

sudo pip install uwsgi

not running on a virtualenv on this machine 🙁

what I’ve found really hard to fix was the wrong filesystem encoding wich lead to the famous encoding errors:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' inposition 86: ordinal not in range(128)

The fix is trivial: you must convince uwsgi that is running in an UTF-8 locale, to do so, you must set environment vars as explained in django docs   (for apache/mod_python, but the root is the same).

Having had an hard time to set env on upstart, I’ve switched to a standard init script for uwsgi:

#! /bin/bash
# /etc/init.d/uwsgi
#

daemon=/usr/bin/uwsgi
pid=/tmp/project-master.pid
# run as www-data
args="--uid=33 --gid=33 --ini /home/public_html/project/uwsgi.ini --pidfile $pid"

# Carry out specific functions when asked to by the system
case "$1" in
    start)
        echo "Starting uwsgi"
        LC_ALL='en_US.UTF-8' LANG='en_US.UTF-8' start-stop-daemon -p $pid --start --exec $daemon -- $args
        ;;
    stop)
        echo "Stopping script uwsgi"
        LC_ALL='en_US.UTF-8' LANG='en_US.UTF-8' start-stop-daemon --signal INT -p $pid --stop $daemon -- $args
        ;;
    reload)
        echo "Reloading conf"
        kill -HUP $(cat $pid)
        ;;
    *)
        echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
        exit 1
    ;;
esac

exit 0

Here the trick is to set env vars on the start-stop-daemon line.

The application ini is something like:

[uwsgi]
chdir=/home/public_html/project/
master=True
vacuum=True
max-requests=5000
daemonize=/var/log/uwsgi/uwsgi.log
socket=127.0.0.1:49152
env = DJANGO_SETTINGS_MODULE=settings
module = django.core.handlers.wsgi:WSGIHandler()

Last missing piece is log rotation:

 

"/var/log/uwsgi/*.log" {
  copytruncate
  daily
  rotate 5
  compress
  delaycompress
  missingok
  notifempty
}
It's only fair to share...Tweet about this on TwitterShare on FacebookShare on LinkedInPin on PinterestShare on RedditShare on Google+

6 Responses to “django deployment with nginx and uwsgi”

  • Mihnea Simian

    uwsgi command line options now supports setting environment variables. Simply add to args:
    –env LC_ALL=’en_US.UTF-8′
    –env LANG=’en_US.UTF-8′

    Actually, I think the first one implies the second.

    Thanks for the hint!

  • Marcin

    Thank a lot for this post and for the comment above!

    Based on your input, I worked it around by specifying:
    LC_ALL=en_US.UTF-8
    in my /etc/uwsgi/apps-enabled/instance.xml

    Please note that I’m using XML syntax (see: http://uwsgi-docs.readthedocs.org/en/latest/Configuration.html#xml-files ), but you could also do it in JSON/INI or any other syntax

    To verify you are experiencing this problem, add the following print in your uwsgi-hosted Python app:

    print (locale.getlocale(), locale.getpreferredencoding())

    Should be something like ((‘en_US’, ‘UTF-8’), UTF-8)
    but was ((None, None), ANSI_X3.4-1968) for me (hence UnicodeEncodeError when encoding unicode to str).

  • aRkadeFR (@aRkadeFR)

    Do you know if there’s any kind of -HUP signal possible to uwsgi so django reopen the file descriptors to the log files?

    Thank you for the article 😉

  • luke

    You can add this to your
    /etc/uwsgi-emperor/vassa;s/my-site-config-ini file
    env = LANG=en_US.utf8