CentOSでnginx+uwsgi+djangoを試してみる

nginx+FastCGI+Wordpressの組み合わせはやってみたので、次は nginx+uwsgi+django の組み合わせで簡単なサービスを作ってみたい。
とりあえず、django の admin ページが見られるようになるまで。
思い切り uwsgi のページやその他のページの丸パクリだけど…。

必要な物をCentOS 5.7にインストール

必要なのは大雑把に言うと以下の通り

以下、それぞれのインストールについて。


Python
手順は以下のページのまんま

一つ注意しなければいけないのは、django のデータベースに sqlite3 を使うつもりなら python をビルドする前に sqlite-devel をインストールしておかなければならないという事。

[paraches@localhost Python-2.7.2]$ sudo yum install sqlite-devel

sqlite-devel がない場合 sqlite3 のモジュールが組み込まれない。

Python build finished, but the necessary bits to build these modules were not found:
_bsddb             _curses            _curses_panel   
_sqlite3           _tkinter           bsddb185        
bz2                dbm                dl              
gdbm               imageop            readline        
sunaudiodev                                           
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

結果、djangopython manage.py syncdb しようとした時にエラーになる。

[paraches@localhost myApps]$ python manage.py syncdb
<省略>
django.core.exceptions.ImproperlyConfigured: Error loading either pysqlite2 or sqlite3 modules (tried in that order): No module named _sqlite3
[paraches@localhost myApps]$ 


Django
Django のインストールは pip install django でサクっと。

[paraches@localhost ~]$ sudo pip install django
Downloading/unpacking django
  Downloading Django-1.3.1.tar.gz (6.5Mb): 6.5Mb downloaded
  Running setup.py egg_info for package django
    
Installing collected packages: django
  Running setup.py install for django
    changing mode of build/scripts-2.7/django-admin.py from 644 to 755
    
    changing mode of /usr/local/bin/django-admin.py to 755
Successfully installed django
Cleaning up...
[paraches@localhost ~]$ 

今回は 1.3.1 がインストールされた。


設定などは基本的に以下のページのまんま。

とりあえず Django の動作確認。
プロジェクトは /var/www/django に myApps を作成。
その後 settngs ファイルのデータベース設定と Admin の編集して、pyton manage.py runserver で画面が表示されるのを確認。

[paraches@localhost django]$ django-admin.py startproject myApps
[paraches@localhost myApps]$ vi settings.py
[paraches@localhost myApps]$ python manage.py runserver


uwsgi
uwsgi も pip install uwsgi でサクっとインストール。

[paraches@localhost ~]$ sudo pip install uwsgi

取り敢えずはインストールだけ。
何通りかの方法で動作確認したりするので、設定などは後で。


nginx
手順は以下のページのまんま

今回は Wordpress とリバースプロクシは関係なしで、nginx を入れるだけ。

uwsgi の動作確認

とりあえず uwsgi の動作確認の為に /var/www/html に hello.py を用意。

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World"

で、uwsgi を起動

uwsgi --socket 127.0.0.1:9090 --file /var/www/html/hello.py

ポート 9090 へのアクセス?があったら /var/www/html/hello.py が起動される。

次に nginx.conf を修正して www.example.com/ にアクセスすると先ほど起動した uwsgi を呼び出すようにした。

        location / {
            include     uwsgi_params;
            uwsgi_pass  127.0.0.1:9090;
        }

nginx に設定を読み込ませた後で、ブラウザから www.example.com にアクセスすると…

ちゃんと表示された!

uwsgiとdjangoの動作確認

次に uwsgi と django で動作確認をしてみる。
uwsgi は設定ファイル(django.ini)を作って起動する。
下記の django.ini は Quickstart のサンプルに static ファイル用のオプションを加えてパスを自分の環境に合わせただけ。

[uwsgi]
http = :8000
chdir = /var/www/django/myApps
pythonpath = /var/www/django
env = DJANGO_SETTINGS_MODULE=myApps.settings
module = django.core.handlers.wsgi:WSGIHandler()
static-map = /static/admin=/usr/local/lib/python2.7/site-packages/django/contrib/admin/media

これをコマンドラインから起動

uwsgi --init django.ini

ブラウザからサーバのポート 8000 にアクセスすると…

ちゃんと管理者のページが表示される。

nginxとuwsgiとdjango を組み合わせる

今回は www.example.com/ にアクセスすると django のアプリケーションが起動するようにする。
流れはこんな感じ
1.www.example.com/ へのアクセスを nginx が受け取る
2.nginx がそれを 127.0.0.1:9090 で待ってる uwsgi へ渡す
3.uwsgi は起動時に指定されている django のハンドラを呼ぶ
これで django が起動してレスポンスが返される。


まずは nginx の nginx.conf の http 部分はこんな感じ。

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile         on;

    keepalive_timeout  5;

    gzip             on;
    gzip_disable     "MSIE [1-6]\.";

    server {
        listen       80;
        server_name  www.example.com;


        location / {
            include     uwsgi_params;
            uwsgi_pass  127.0.0.1:9090;
       }

        location /static/admin {
            alias /usr/local/lib/python2.7/site-packages/django/contrib/admin/media;
        }

    }

    # Load config files from the /etc/nginx/conf.d directory
    include /etc/nginx/conf.d/*.conf;
}

/static/admin の部分は css などの静的ファイル用。


で、次に uwsgi だけどまずはコマンドラインで起動している下記方法を真似する。

準備するファイルは django 起動用の /var/www/django/wsgi_app.py。
内容は以下の通り。

import os
import sys
import django.core.handlers.wsgi

os.environ['DJANGO_SETTINGS_MODULE'] = 'myApps.settings'
application = django.core.handlers.wsgi.WSGIHandler()

で、uwsgi を以下のコマンドラインで起動。

uwsgi --socket 127.0.0.1:9090 --pp /var/www/django --module wsgi_app

これで www.example.com/admin にアクセスすると、ちゃんと django の管理者ページが表示される。


最後に uwsgi を自動的に起動するようにしている下記方法を真似してみる。

uwsgi の起動用に準備するファイルが結構ある。

起動スクリプトと起動設定ファイルは、uwsgi の場所と uid 以外はまんまコピーで。
設定ファイルは自分の django の設定に合わせてパスなんかを変更。あ、あとはポート番号も。


ファイルの準備ができたら、uwsgi を chkconfig --add uwsgi で登録して、start で起動。

[paraches@localhost etc]$ sudo chmod +x /etc/init.d/uwsgi
[paraches@localhost etc]$ sudo /sbin/chkconfig --add uwsgi
[paraches@localhost etc]$ sudo /etc/init.d/uwsgi start
uwsgi を起動中: [uWSGI] getting YAML configuration from /etc/uwsgi.yaml
                                                           [  OK  ]
[paraches@localhost etc]$ 

これで www.example.com/admin にアクセすると、ちゃんと django の管理者ページが表示される。

ここで nginx のエラーメッセージが出たり、uWSGI のエラーが出る場合は /var/log/uwsgi.log を見ると何が問題なのか大抵の場合はわかるんじゃないかな。


エラーが出ずにちゃんと動いたので、uwsgi をサーバ起動時に動作させるようにする。

[paraches@localhost etc]$ sudo /sbin/chkconfig --level 345 uwsgi on

というわけで、nginx+uwsgi+django も動くようになりました!