nginx + FastCGI で Django を動かす
nginx + FastCGI で Django を動かすメモです。
環境: Ubuntu 10.04 nginx 0.8.53 MySQL 5.1.41 Python 2.6.5 Django 1.2.3
下準備
pip のインストール pip でパッケージ管理を行うようにします。 easy_install をインストールして、easy_install で pip をインストールします。
% sudo aptitude install python-setuptools
% sudo easy_install pip
これ以降は virtualenv で作成したサンドボックスにパッケージをインストールしています。 virtualenv って何?という方は以下の記事を読んでみると幸せになれます。
参考:Python 開発環境 | Go for it! http://blog.mitsukuni.org/2010/10/25/python-development-environment 参考:virtualenv, virtualenvwrapper, pip を使う方法 - Ian Lewis http://www.ianlewis.org/jp/virtualenv-pip-fabric
Django のインストール Django!! Django!!
% sudo pip install django
flup のインストール FastCGI を使用するためのライブラリです。
% sudo pip install flup
mysql-python のインストール Python から MySQL に接続するためのライブラリです。
# mysql_config が入っていなかったのでインストール
% sudo aptitude install libmysqlclient-dev
# Python のヘッダファイル/静的ライブラリをインストール
# (インストールしないと mysql-python のインストールでコケる)
% sudo aptitude install python-dev
% pip install mysql-python
FastCGI の設定
Django FastCGI の起動スクリプトを作成 以下のサイトから引っ張ってきて、編集します。
参考:InitdScriptForLinux - Django - Trac http://code.djangoproject.com/wiki/InitdScriptForLinux
今回の環境だと以下のようになります。
/etc/init.d/django-fastcgi
#! /bin/bash
### BEGIN INIT INFO
# Provides: FastCGI servers for Django
# Required-Start: networking
# Required-Stop: networking
# Default-Start: 2 3 4 5
# Default-Stop: S 0 1 6
# Short-Description: Start FastCGI servers with Django.
# Description: Django, in order to operate with FastCGI, must be started
# in a very specific way with manage.py. This must be done
# for each DJango web server that has to run.
### END INIT INFO
#
# Author: Guillermo Fernandez Castellanos
# <guillermo.fernandez.castellanos AT gmail.com>.
#
# Version: @(#)fastcgi 0.1 11-Jan-2007 guillermo.fernandez.castellanos AT gmail.com
#
#### SERVER SPECIFIC CONFIGURATION
DJANGO_SITES="hogeproject"
SITES_PATH=/var/www/hoge/public_html
RUNFILES_PATH=/tmp/run
VIRTUALENV_PATH=/home/chocoby/.virtualenvs
HOST=127.0.0.1
PORT_START=3000
RUN_AS=www-data
FCGI_METHOD=prefork
#### DO NOT CHANGE ANYTHING AFTER THIS LINE!
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="FastCGI servers"
NAME=$0
SCRIPTNAME=/etc/init.d/$NAME
#
# Function that starts the daemon/service.
#
d_start()
{
# Starting all Django FastCGI processes
PORT=$PORT_START
for SITE in $DJANGO_SITES
do
echo -n ", $SITE"
if [ -f $RUNFILES_PATH/$SITE.pid ]; then
echo -n " already running"
else
source $VIRTUALENV_PATH/$SITE/bin/activate
start-stop-daemon --start --quiet \
--pidfile $RUNFILES_PATH/$SITE.pid \
--chuid $RUN_AS --exec /usr/bin/env -- python \
$SITES_PATH/$SITE/manage.py runfcgi \
method=$FCGI_METHOD \
host=$HOST port=$PORT pidfile=$RUNFILES_PATH/$SITE.pid
chmod 400 $RUNFILES_PATH/$SITE.pid
fi
let "PORT = $PORT + 1"
done
}
#
# Function that stops the daemon/service.
#
d_stop() {
# Killing all Django FastCGI processes running
for SITE in $DJANGO_SITES
do
echo -n ", $SITE"
start-stop-daemon --stop --quiet --pidfile $RUNFILES_PATH/$SITE.pid \
|| echo -n " not running"
if [ -f $RUNFILES_PATH/$SITE.pid ]; then
rm $RUNFILES_PATH/$SITE.pid
fi
done
}
ACTION="$1"
case "$ACTION" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
restart|force-reload)
echo -n "Restarting $DESC: $NAME"
d_stop
sleep 1
d_start
echo "."
;;
*)
echo "Usage: $NAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
exit 0
元々のスクリプトから何点か変更しています。それも含めて設定する部分を説明します。 元々の項目
- /bin/bash : source コマンドを使用するので /bin/sh から /bin/bash に変更
- DJANGO_SITES :Django のプロジェクト名を指定
- SITES_PATH :プロジェクトディレクトリが存在しているディレクトリのパスを指定
- RUNFILES_PATH :プロセス ID を記録しておく .pid ファイルを設置するディレクトリのパスを指定
- FCGI_METHOD :threaded から prefork に変更
新たに追加した項目
- VIRTUALENV_PATH : virtualenv のサンドボックスが置いてあるディレクトリのパス
今回は virtualenv を使用しているので、FastCGI を起動する前にプロジェクト用の virtualenv を activate しています。 VIRTUALENV_PATH にサンドボックスが置かれているディレクトリのパスを指定します。
サンドボックス名は DJANGO_SITES で設定しているプロジェクト名と対応させます。 51 行目に追加しているのですが、start-stop-daemon コマンドの前に source コマンドを使用し、そのサンドボックス内の /bin/activate を実行することによって、サンドボックスを activate しています。 こうすることで、プロジェクト毎にサンドボックス内のパッケージを使用できるようになります。(@key3++)
virtualenv を使用しない場合は追加する必要はありません。
scp などで転送した場合は所有者を変更しておく
% sudo chown root:root /etc/init.d/django-fastcgi
システム起動時に起動させる
% sudo update-rc.d django-fastcgi defaults
.pid ファイルを置いておくディレクトリを作成する 作成する場所は、起動スクリプトの RUNFILES_PATH に書いてあるディレクトリ。
% sudo mkdir /tmp/run
% sudo chown www-data:www-data /tmp/run
nginx の設定
サイトを置いておくディレクトリを作成
% sudo mkdir -p /var/www/hoge/{logs,public_html}
public_html の中にプロジェクトのディレクトリを置く 例:/var/www/hoge/public_html/hogeproject
nginx の設定ファイルを作成 /etc/nginx/sites-available/hoge
server {
listen 80;
server_name hoge;
access_log /var/www/hoge/logs/access.log;
error_log /var/www/hoge/logs/error.log;
location / {
fastcgi_pass 127.0.0.1:3000;
include /etc/nginx/fastcgi_params_django;
}
location /static {
root /var/www/hoge/public_html/hogeproject;
}
location /media {
alias /home/chocoby/.virtualenvs/hogeproject/lib/python2.6/site-packages/django/contrib/admin/media;
}
}
/static は、プロジェクトの CSS ファイルや画像素材などの静的ファイルが置いてあるのディレクトリ。 /media は、管理画面の静的ファイルが置いてあるディレクトリ。
元々ある、/etc/nginx ディレクトリの fastcgi_params を include していると、SCRIPT_NAME が渡されてトップページのみしか表示されない現象が発生してしまうので 削除しておきます。(@key3++) それに加えて Django 用のパラメーターも追加。
sites-available の設定に直接パラメーターを書いても良いのですが、再利用することを考えて、/etc/nginx ディレクトリに fastcgi_params_django というファイルを作成し include するようにしています。
/etc/nginx/fastcgi_params_django
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# Django
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
sites-enabled ディレクトリにシンボリックリンクを張って有効化
% sudo ln -s /etc/nginx/sites-available/hoge /etc/nginx/sites-enabled
FastCGI を起動し、nginx に設定を再読込させる
% sudo /etc/init.d/django-fastcgi start
% sudo nginx -s reload
あとは、settings.py を環境に合わせ、manage.py syncdb などをして完了です。