Nginx + WSGI + Pylons環境の構築方法



ネットをぷらついていたら、

Nginx + WSGI == Blazing Fast!
http://groups.google.co.jp/group/webpy/browse_thread/thread/53a4f45de8ab96ed

おお、Nginxにmod_wsgi moduleが存在するとは。
http://wiki.codemongers.com/NginxNgxWSGIModule


例はweb.pyですが、これってPylonsも動かせるんじゃ・・・

※Nginx自体はちょっと触ったことがあります。
http://fujishinko.exblog.jp/7686541/


早速挑戦です。

まず、webサーバのNginxをダウンロード
http://nginx.net/
ここから
nginx-0.6.34.tar.gz
をダウンロード

wsgiモジュール
http://hg.mperillo.ath.cx/nginx/mod_wsgi/archive/tip.tar.gz
ここからnginx/mod_wsgiをダウンロード


/usr/local/src/

に取得したモジュールをコピーします。


ディレクトリ移動、解凍など実行します。

#ディレクトリ移動
#cd /usr/local/src

#解凍
#tar zxvf nginx-0.6.34.tar.gz
#tar zxvf mod_wsgi-8994b058d2db.tar.gz

#名前が長いのでmod_wsgiにリネーム
#mv mod_wsgi-8994b058d2db mod_wsgi



コンパイルするために移動

#cd nginx-0.6.34



とりあえず、configure

#./configure




checking for OS
+ Linux 2.6.18-6-686 i686
checking for C compiler ... not found

./configure: error: C compiler gcc is not found



ああ、Debian自体インストール直後なのでgccとかが入ってませんでした。


ここを参考に
Debian の開発用パッケ-ジを入忘れたら, 何を apt-get するか?
http://www.math.kobe-u.ac.jp/~kodama/tips-SetDevelDebian.html


#apt-get install gcc
#apt-get install make
#apt-get install libc6-dev
#apt-get install python
#apt-get install python-dev

#./configure
...
Configuration summary
+ PCRE library is not found
+ OpenSSL library is not used
+ md5 library is not used
+ sha1 library is not used
+ zlib library is not found



うーん。たりないモノがあるらしい。

ここを参考に
http://hdknr.spaces.live.com/blog/cns!82BB74511E950AA4!1290.entry



#RCREで必用
#apt-get install libpcre3-dev
#sslとzlib
#apt-get install libssl-dev


これで、configureは通るようになりました。
さっそく、--add-moduleオプションをつけてみます。


#./configure --add-module=/usr/local/src/mod_wsgi/
#make
/usr/local/src/mod_wsgi//src/ngx_http_wsgi_handler.c:74:
warning: implicit declaration of function 'ngx_http_discard_body'


というエラーでmakeに失敗します。
宣言していない関数を使っている模様ですがどうしたのもか。

悩んでいたのですが・・・
http://wiki.codemongers.com/NginxNgxWSGIModule


From JacobSingh:
I tested this against 0.6.23 and it didn't compile.
Error was: rc/ngx_http_wsgi_handler.c
: In function 'ngx_http_wsgi_handler'
: /root/mod_wsgi-8994b058d2db/src/ngx_http_wsgi_handler.c:74
: warning: implicit declaration of function 'ngx_http_discard_body' make[1]:


よく読んだら、サイトの頭に対処方法が書いてありますね。


You should change that line to read ngx_http_discard_request_body


とのことなので、エラーになる
ngx_http_discard_body
という関数を
ngx_http_discard_request_body
に書き換えます。


#cd /usr/local/src/mod_wsgi/src/
#vi ngx_http_wsgi_handler.c


該当のソースを開いて・・・


/* 74行目付近 */
if (r->method == NGX_HTTP_GET || r->method == NGX_HTTP_HEAD) {
/* XXX not sure */
rc = ngx_http_discard_body(r);


これを


if (r->method == NGX_HTTP_GET || r->method == NGX_HTTP_HEAD) {
/* XXX not sure */
/* rc = ngx_http_discard_body(r); */
rc = ngx_http_discard_request_body(r);


こんな感じに修正
これでmakeが通るようになりました。

本気モードでconfigure

#./configure --add-module=/usr/local/src/mod_wsgi/ --sbin-path=/sbin/nginx
--conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid
--with-http_ssl_module --with-md5=auto/lib/md5 --with-sha1=auto/lib/sha1

※実際は一行


Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ using md5 library: auto/lib/md5
+ using sha1 library: auto/lib/sha1
+ using system zlib library

nginx path prefix: "/usr/local/nginx"
nginx binary file: "/sbin/nginx"
nginx configuration prefix: "/usr/local/nginx"
nginx configuration file: "/usr/local/nginx/nginx.conf"
nginx pid file: "/usr/local/nginx/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "/usr/local/nginx/client_body_temp"
nginx http proxy temporary files: "/usr/local/nginx/proxy_temp"
nginx http fastcgi temporary files: "/usr/local/nginx/fastcgi_temp"



後はお決まりのmake,make installでインストール完了です。


webサーバは入りましたので、次はPylonsのインストール。

前やった「Python apache2 + mod_wsgi で Pylons を動かす」
http://fujishinko.exblog.jp/7703789/
を参考に


■プロキシ設定

#vi ~/.bashrc
export HTTP_PROXY=http://プロキシサーバ:ポート
#source ~/.bashrc



■Pylonsインストール

#wget http://peak.telecommunity.com/dist/ez_setup.py
#python ez_setup.py Pylons==0.9.6.2



■サンプル用のアプリケーションを作成

#mkdir /usr/local/pylons/
#cd /usr/local/pylons/
#paster create -t pylons helloworld
#cd helloworld/
#paster controller hello



■デバッグ設定を解除

#vi /usr/local/pylons/helloworld/development.ini

[DEFAULT]
#debug = true
debug = false

[app:main]
set debug = false



■nginx <-> Pylonsの設定ファイル置き場

#mkdir /usr/local/pylons/helloworld/nginx

#vi /usr/local/pylons/helloworld/nginx/helloworld.wsgi
import os, sys
sys.path.append('/usr/local/pylons/helloworld')
os.environ['PYTHON_EGG_CACHE'] = '/usr/local/pylons/python-eggs'

from paste.deploy import loadapp
application = loadapp('config:/usr/local/pylons/helloworld/development.ini')



■nginxの設定

#wsgi用の設定ファイルをコピー

#mkdir /usr/local/nginx/conf
#cp /usr/local/src/mod_wsgi/conf/wsgi_vars /usr/local/nginx/conf/

#nginxの設定を変更
#vi /usr/local/nginx/nginx.conf


nginx.confの内容

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid    logs/nginx.pid;


events {
  worker_connections 1024;
}


http {
  include    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 logs/access.log main;

  sendfile    on;
  #tcp_nopush   on;

  #keepalive_timeout 0;
  keepalive_timeout 65;

  #gzip on;

  server {
    listen   80;
    server_name localhost;

#このincludeをたす
    include conf/wsgi_vars;

    #charset koi8-r;

    #access_log logs/host.access.log main;

    location / {
      root html;
      index index.html index.htm;
    }

#このセクションをたす
    location /helloworld {
     wsgi_pass /usr/local/pylons/helloworld/nginx/helloworld.wsgi;
    }


    #error_page 404       /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }
}



#/sbin/nginx

で起動

http://www.example.com/helloworld/

で見えるはず。


nginxの停止は
/usr/local/nginx/nginx.pid
に書かれているpidをkillしなくてはいけません。

面倒なので、起動スクリプトを作りました。


#vi /etc/init.d/nginx

#! /bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: nginx web server
# Description: nginx web server
### END INIT INFO

DESC="nginx web server"
NAME=nginx
DAEMON=/sbin/$NAME
PIDFILE=/usr/local/nginx/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
 start)
    $DAEMON
    ;;
 stop)
    kill `cat $PIDFILE`
    ;;
 *)
    echo "Usage: $SCRIPTNAME {start|stop}" >&2
    exit 1
    ;;
esac



#chmod +x /etc/init.d/nginx
#/etc/init.d/nginx start
#/etc/init.d/nginx stop


で使えます。


update-rc.d nginx start 90 2 3 4 5 . stop 10 0 1 6 .

で自動起動できるはず。


※まだまだ、起動スクリプトはニガテです。


もどる