在这之前我的youflog 是用fcgi的方式部署在nginx上的.
但fcgi不是python web server的标准,wsgi才是,wsgi的实现方法有很多,其中uwsgi算是很优秀的一个。
http://projects.unbit.it/uwsgi/
uwsgi是一个用c语言开发的一个wsgi服务器,旨在提供专业的 Python web应用发布和开发.
所以决定把fcgi改成uwsgi。
uwsgi的安装
1.下载uwsgi 当前最新的版本是 0.9.6.6
2.编译uwsgi
由于uwsgi需要libxml2库的支持 需要将libxml2先安装上 apt-get install python-dev libxml2-dev
tar zxvf uwsgi-0.9.6.6.tar.gz
cd uwsgi-0.9.6.6
make -f Makefile.Py26 (指定你python的版本,如果你的python是3.0 就应该是 make -f Makefile.Py3.0)
编译成功后就会在当前目录下生成一个uwsgi的可执行文件
cp uwsgi /usr/sbin/uwsgi
安装Nginx
nginx在0.8的版本以前是不支持wsgi的 因此在编译nginx的时候需要指定uwsgi路径
下面是针对 ubuntu 用户
cd /etc/nginx/sites-available
vi default
运行uwsgi
nginx -s reload
在浏览器中输入http://localhost , 完成.
from http://iyouf.info/nginx-uwsgi-youflog.html
-------------------------------------------------------
反观python,部属起来真是头痛,常见的部署方法有:
如果有个啥东东能像php-cgi一样监听同一端口,进行统一管理和负载平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才发现居然一直不知道有那么方便地统一部署工具。
uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的10倍那么快,有个比较见下图

uWSGI的主要特点如下,其中一些功能让我感动得泪流满面
再到project目录建立myapp.py,使得application调用框架的wsgi接口,比如web.py就是
再比如django就是
然后运行uwsgi监听9090,其中-w后跟模块名,也就是刚才配置的myapp
运行网站发现已经部署完成了。
并发4个线程
主控制线程+4个线程
执行超过30秒的client直接放弃
限制内存空间128M
服务超过10000个req自动respawn
后台运行等
更多用法见文档:http://projects.unbit.it/uwsgi/wiki/Doc
然后必须配置virtualenv,virtualenv是python的一个很有用的虚拟环境工具,这样安装
然后设置一个/多个app基准环境
应用环境,在此环境下安装的软件仅在此环境下有效
最后配置nginx,注意每个站点必须单独占用一个server,同一server不同location定向到不同的应用不知为何总是失败,我猜也算是一个bug。
如此这般,重启nginx服务,两个站点就可以共用一个uwsgi服务了。
于是uwsgi的监控信息可以在http://uwsgiadmin.django.obmem.info 看到用户名密码都是admin。
再比如LBForum论坛程序的部署:根据安装说明安装完毕,再按部署说明修改完配置文件,然后只需修改nginx配置文件:
于是 http://lbforum.django.obmem.info 就是论坛程序了。
python世界很有趣,一直会发现好玩的东东,但是python世界也很折腾人,大部分东东都是dev版本,文档缺失,各种兼容问题……大约是因为在python中,有个idea到实现出来实在是太过高效的关系吧,唉,被折腾死了。
from http://obmem.info/?p=703
------------------------------------------------------------------------
( 简单点写,就是这样:
server {
listen 80;
server_name yl.britesea.info;
root /root/youflog;
location / {
} )
现在看我们的Django app如何配置。
首先在你的django app目录创建个wsgi.py 文件,内容如下:
from http://blog.hysia.com/post/2/nginx-uwsgi-deploy-django-apps/
-------------------------------------------------------------------------------
首先下载编译 uwsgi:
编译完后将得到的 uwsgi 复制到系统目录:
启动 uwsgi:
这个命令可以放入
这样启动的 uwsgi 可以被多网站共用,nginx 的 server 块配置如下:
如果要多加一个网站,只需在 nginx 配置中新加个 server 块,改变下
如果要让 uwsgi 重新载入,可以执行:
from http://ichuan.net/post/6/using-uwsgi-instead-of-fastcgi-for-django-app/ (此文不错,我设置成功.示例网站:http://dj.britesea.info)
(如果django app是youflog,则操作如下:
假设youflog上传到了/root/youflog/下,则启动uwsgi的命令为:
Python 2.6.5 + Django 1.2.1 + Nginx Installation &Configuration
一、install
## 万恶的XXX,封掉了python下的所有目录,首页上的download链接是打不开的,不过可以到其他的链接下载 ##
## 1、http://ftp.python.org/ftp/python/2.6.5/
## 2、http://www.python.org/ftp/python/
1. Python 2.6.5
1) install
## add the /opt/python26/bin to the PATH
vi /etc/profile
###########################
PATH=”$PATH:/opt/mysql/bin:/opt/python/bin:/opt/nginx/sbin:/opt/python26/bin”;export PATH
###########################
2)test
2. PIL
1) install
2) test
3. setuptools
4. flup
5. MySQL-python
1) install
2) test
6 Django 1.2.1
1) install
or
2) test
7. django-treebeard
1) install
2) test
二. configure
1) nginx
## 这里不能使用nginx默认的fastcgi_params,测试的时候发现所有的页面都会跳转到首页,而且也不报错
## 貌似是SCRIPT_NAME所引起的问题,而Django好像使用的是PATH_INFO,为了避免和其他的fcgi冲突,所以新建一个django专用的fastcgi_params_django
## Python2.4 + Django 0.96 版本不需要,因为Django 0.96 还不支持SCRIPT_NAME
## 可以查看django的django\core\handlers目录下的modpython.py 文件
2) fcgi
但fcgi不是python web server的标准,wsgi才是,wsgi的实现方法有很多,其中uwsgi算是很优秀的一个。
http://projects.unbit.it/uwsgi/
uwsgi是一个用c语言开发的一个wsgi服务器,旨在提供专业的 Python web应用发布和开发.
所以决定把fcgi改成uwsgi。
uwsgi的安装
1.下载uwsgi 当前最新的版本是 0.9.6.6
2.编译uwsgi
由于uwsgi需要libxml2库的支持 需要将libxml2先安装上 apt-get install python-dev libxml2-dev
tar zxvf uwsgi-0.9.6.6.tar.gz
cd uwsgi-0.9.6.6
make -f Makefile.Py26 (指定你python的版本,如果你的python是3.0 就应该是 make -f Makefile.Py3.0)
编译成功后就会在当前目录下生成一个uwsgi的可执行文件
cp uwsgi /usr/sbin/uwsgi
安装Nginx
nginx在0.8的版本以前是不支持wsgi的 因此在编译nginx的时候需要指定uwsgi路径
下面是针对 ubuntu 用户
sudo add-apt-repository ppa:nginx/stable apt-get update apt-get install nginx最后就是把django的应用部署到nginx上去
cd /etc/nginx/sites-available
vi default
server { listen 0.0.0.0:80; ## listen for ipv4; this line is default and implied #listen [::]:80 default ipv6only=on; ## listen for ipv6 location / { include uwsgi_params; uwsgi_pass 0.0.0.0:8080; } location /favicon.ico { alias /opt/youflog/static/favicon.ico; } #error_page 404 /404.html; }配置就是location / {...} 部分 比cgi的的简单了许多
运行uwsgi
cd /opt/youflog uwsgi -s 0.0.0.0:8080 -M -d /var/log/uwsgi.log --pythonpath=`pwd` --module=wsgi运行nginx
nginx -s reload
在浏览器中输入http://localhost , 完成.
from http://iyouf.info/nginx-uwsgi-youflog.html
-------------------------------------------------------
配置Nginx+uwsgi更方便地部署python app
个人觉得php最方便的就是deployment了,只要把php文件丢到支持php的路径里面,然后访问那个路径就能使用了;无论给主机添加多少php应用,只要把目录改好就没你的事了,完全不用关心php-cgi运行得如何,deployment极为方便。反观python,部属起来真是头痛,常见的部署方法有:
- fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务互动
- wsgi:利用http服务的mod_wsgi模块来跑各个project
如果有个啥东东能像php-cgi一样监听同一端口,进行统一管理和负载平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才发现居然一直不知道有那么方便地统一部署工具。
uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的10倍那么快,有个比较见下图
uWSGI的主要特点如下,其中一些功能让我感动得泪流满面
- 超快的性能
- 低内存占用(实测为apache2的mod_wsgi的一半左右)
- 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
- 详尽的日志功能(可以用来分析app性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
If you are searching for a simple wsgi-only server, uWSGI is not for you, but if you are building a real (production-ready) app that need to be rock-solid, fast and easy to distribute/optimize for various load-average, you will pathetically and morbidly fall in love (we hope) with uWSGI. 正式开工
uwsgi的文档虽然蛮多也很详细,但是他们网站的排版真是让人无语,粗粗看上去根本不知道文档在哪里。其实是在这里:http://projects.unbit.it/uwsgi/wiki/Doc0.安装uwsgi
ubuntu有uwsgi的ppaadd-apt-repository ppa:stevecrozz/ppa apt-get update apt-get install uwsgi
1. 用uwsgi代替mod_wsgi
nginx的整体配置说来话长,我也不再罗嗦了,假设已经明白nginx的基本配置,那么uwsgi就类似这么配置:location / {
include uwsgi_params
uwsgi_pass 127.0.0.1:9090
}这就是把所有url传给9090端口的uwsgi协议程序来互动。再到project目录建立myapp.py,使得application调用框架的wsgi接口,比如web.py就是
...... app = web.application(urls, globals()) application = app.wsgifunc()
....... from django.core.handlers.wsgi import WSGIHandler application = WSGIHandler()
uwsgi -s :9090 -w myapp
2. uwsgi的参数
以上是单个project的最简单化部署,uwsgi还是有很多令人称赞的功能的,例如并发4个线程
uwsgi -s :9090 -w myapp -p 4
uwsgi -s :9090 -w myapp -M -p 4
uwsgi -s :9090 -w myapp -M -p 4 -t 30
uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128
uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000
uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log
3.为uwsgi配置多个站点
为了让多个站点共享一个uwsgi服务,必须把uwsgi运行成虚拟站点:去掉“-w myapp”加上”–vhost”uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost
apt-get install python-setuptools easy_install virtualenv
virtualenv /var/www/myenv
source /var/www/myenv/bin/activate pip install django pip install mako ...
server { listen 80; server_name app1.mydomain.com; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090; uwsgi_param UWSGI_PYHOME /var/www/myenv; uwsgi_param UWSGI_SCRIPT myapp1; uwsgi_param UWSGI_CHDIR /var/www/myappdir1; } } server { listen 80; server_name app2.mydomain.com; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090; uwsgi_param UWSGI_PYHOME /var/www/myenv; uwsgi_param UWSGI_SCRIPT myapp2; uwsgi_param UWSGI_CHDIR /var/www/myappdir2; } }
4.实战应用
最初的设置完毕以后,再添加的应用,只需要在nginx里面进行少量修改,无需重启uwsgi,就能立刻部署完毕。uwsgi自带了基于django的监控uwsgi运行状态的工具,就拿它来部署好了:server { listen 80; root /var/www/django1.23; index index.html index.htm; server_name uwsgiadmin.django.obmem.info; access_log /var/log/nginx/django.access.log; location /media/ { root /var/www/django1.23/adminmedia; rewrite ^/media/(.*)$ /$1 break; } location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090; uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv; uwsgi_param UWSGI_CHDIR /var/www/django1.23/uwsgiadmin; uwsgi_param UWSGI_SCRIPT uwsgiadmin_wsgi; } }
再比如LBForum论坛程序的部署:根据安装说明安装完毕,再按部署说明修改完配置文件,然后只需修改nginx配置文件:
server { listen 80; root /var/www/django1.23; index index.html index.htm; server_name lbforum.django.obmem.info; access_log /var/log/nginx/django.access.log; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090; uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv; uwsgi_param UWSGI_CHDIR /var/www/django1.23/LBForum/sites/default; uwsgi_param UWSGI_SCRIPT lbforum_wsgi; } }
后记
虽然写出来寥寥几行,配置的时候我可吃尽了uwsgi的苦头,有些想当然的用法完全不能成立,–no-site参数一加上去其他都好使LBForum怎么都部署不了,一开始多站点公用uwsgi怎么都成功不了等等。python世界很有趣,一直会发现好玩的东东,但是python世界也很折腾人,大部分东东都是dev版本,文档缺失,各种兼容问题……大约是因为在python中,有个idea到实现出来实在是太过高效的关系吧,唉,被折腾死了。
from http://obmem.info/?p=703
------------------------------------------------------------------------
用Nginx+uWSGI部署django app
常见的django webapp 部署方式采用FCGI 或 WSGI的方式部署,今天我这备忘下采用uWSGI的部署方式。 目前我这博客就是采用 Nginx + uWSGI + Python + Django 构建的,部署虽没有php那样扔到目录那么方便,但是并发和性能消耗还是非常不错的。这里不想赘述关于FCGI, WSGI,uWSGI之间的比较,网上关于这样的对比测试也有很多,例如这里和 这里。这里说下部署过程。 uWSGI 的官方网站 http://projects.unbit.it/uwsgi/ wiki介绍的很详细。 Nginx关于HttpUwsgiModule的介绍http://wiki.nginx.org/HttpUwsgiModule.有这些资料参考,安装部署是很容易的事情。- uWSGI的安装
wget http://projects.unbit.it/downloads/uwsgi-0.9.9.2.tar.gz
因为我最后采用xml配置django app 的部署,所以编译 uWSGI 时候需要把libxml编译进去sudo apt-get install libxml2-dev
剩下的就简单了tar zxvf uwsgi-0.9.9.2.tar.gz
cd uwsgi-0.9.9.2
make -f Makefile.Py26 #指定你python的版本,如果你的python是2.7 就应该是 make -f Makefile.Py27
cp uwsgi /usr/sbin/uwsgi
至此 uWSGI 就算是安装完成了,下一步安装 Nginx > 0.8 的版本,因为只有Nginx > 0.8 的版本才支持wsgi- Nginx 安装
sudo add-apt-repository ppa:nginx/stable
apt-get update
apt-get install nginx
接下来配置Nginx 和 uWSGI部署Django App 了. 首先我们在Nginx中新建一个站点配置文件:sudo vi /etc/nginx/sites-enabled/blog.hysia.com
内容如下:server {
listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
server_name blog.hysia.com;
access_log /var/log/nginx/blog.hysia.com-access.log ;
error_log /var/log/nginx/blog.hysia.com-error.log ;
location / {
uwsgi_pass 127.0.0.1:8630;
include uwsgi_params;
}
}
这样Nginx算是配置完了,( 简单点写,就是这样:
server {
listen 80;
server_name yl.britesea.info;
root /root/youflog;
location / {
uwsgi_pass 127.0.0.1:9001;
include uwsgi_params;}} )
现在看我们的Django app如何配置。
- 配置Django app
首先在你的django app目录创建个wsgi.py 文件,内容如下:
import os,sys
if not os.path.dirname(__file__) in sys.path[:1]:
sys.path.insert(0, os.path.dirname(__file__))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()
然后在app目录创建个django.xml文件,作为uWSGI运行的配置文件,内容如下:<uwsgi>
<socket>127.0.0.1:8630</socket>
<chdir>/home/hysia/website/blog</chdir>
<pythonpath>..</pythonpath>
<module>wsgi</module>
</uwsgi>
最后一步,运行 uWSGI ,重启 Nginx 就行了,如下:uwsgi -x /home/hysia/website/blog/django.xml &
nginx -s reload
就这样你的Django app 就用 uWSGI hold 住了(此文不错,我设置成功,不过下面的文章更好)。当然django.xml的配置远不止这些,比如log文件,内存限制等等,具体的大家可以参看 http://projects.unbit.it/uwsgi/wiki/Example 用uWSGI handle 多个 Django app 的时候性能更出众,更多的探索自己去动手实践吧。from http://blog.hysia.com/post/2/nginx-uwsgi-deploy-django-apps/
-------------------------------------------------------------------------------
用uWSGI替代fastcgi部署django app
uwsgi比 fastcgi 方式快很多。首先下载编译 uwsgi:
http://projects.unbit.it/downloads/uwsgi-0.9.9.1.tar.gz,我是 ubuntu 系统,需要额外装个 libxml2-dev 库:sudo apt-get install libxml2-dev编译完后将得到的 uwsgi 复制到系统目录:
sudo cp uwsgi /usr/sbin/启动 uwsgi:
uwsgi -s /tmp/uwsgi.sock -C -M -p 4 -t 30 --limit-as 128 -R 10000 --vhost -d /tmp/uwsgi.log --pidfile /tmp/uwsgi.pid --pythonpath /var/www
表示用 unix socket 方式执行 uwsgi,-C 表示将 /tmp/uwsgi.sock 文件权限改成 666 以便 nginx 可以读取,-M 表示启动管理进程,-p 4 表示预生成 4 个 worker 子进程,-t 30 是 cgi 程序超时,--limit-as 128 表示限制内存最大 128M,-R 10000 表示每个 worker 处理的最大请求数,--vhost 表示启用虚拟服务器,-d /tmp/uwsgi.log 表示以守护进程方式启动,指定日志文件。这个命令可以放入
/etc/rc.local 作为开机自启动。这样启动的 uwsgi 可以被多网站共用,nginx 的 server 块配置如下:
location / {
uwsgi_pass unix:///tmp/uwsgi.sock;
uwsgi_param UWSGI_CHDIR /var/www/djblog;
uwsgi_param UWSGI_SCRIPT wsgi_app;
include uwsgi_params;
}
上面的配置的前提是,你的 django app在 /var/www/djblog,并且在该目录下有个 wsgi_app.py 文件。文件内容如下:import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'djblog.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
如此配置好后,重启 nginx 就可以了。如果要多加一个网站,只需在 nginx 配置中新加个 server 块,改变下
UWSGI_CHDIR 配置即可。如果要让 uwsgi 重新载入,可以执行:
kill -SIGHUP `cat /tmp/uwsgi.pid`
如果要让停止 uwsgi,可以给它的 master 进程发送 SIGINT 信号:kill -SIGINT `cat /tmp/uwsgi.pid`
uwsgi 的更多配置在此.from http://ichuan.net/post/6/using-uwsgi-instead-of-fastcgi-for-django-app/ (此文不错,我设置成功.示例网站:http://dj.britesea.info)
(如果django app是youflog,则操作如下:
假设youflog上传到了/root/youflog/下,则启动uwsgi的命令为:
uwsgi -s /tmp/uwsgi.sock -C -M -p 4 -t 30 --limit-as 128 -R 10000 --vhost -d /tmp/uwsgi.log --pidfile /tmp/uwsgi.pid --pythonpath /root/然后在/root/youflog/下,新建一个文件wsgi.py,内容如下:import os,sys
if not os.path.dirname(__file__) in sys.path[:1]:
sys.path.insert(0, os.path.dirname(__file__))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler() 然后修改nginx.conf,加入如下内容:
server {
listen 80;
server_name yl.britesea.info;
root /root/youflog;
location / {
uwsgi_pass unix:///tmp/uwsgi.sock;
uwsgi_param UWSGI_CHDIR /root/youflog;
uwsgi_param UWSGI_SCRIPT wsgi;
include uwsgi_params;
}
}
然后重启nginx,
-bash-3.2# /usr/local/nginx/sbin/nginx -s reload
-bash-3.2#
然后访问http://yl.britesea.info,我的youflog就出来了。(在使用uwsgi之前,我的网站为:http://1000.britemoon.info:20000 )
------------------------------------------------------------------------------------Python 2.6.5 + Django 1.2.1 + Nginx Installation &Configuration
一、install
## 万恶的XXX,封掉了python下的所有目录,首页上的download链接是打不开的,不过可以到其他的链接下载 ##
## 1、http://ftp.python.org/ftp/python/2.6.5/
## 2、http://www.python.org/ftp/python/
1. Python 2.6.5
1) install
wget http://ftp.python.org/ftp/python/2.6.5/Python-2.6.5.tgz tar zxvf Python-2.6.5.tgz cd Python-2.6.5 ./configure --prefix=/opt/python26 make make install ln -s /opt/python26/bin/python2.6 /usr/bin/python26
vi /etc/profile
###########################
PATH=”$PATH:/opt/mysql/bin:/opt/python/bin:/opt/nginx/sbin:/opt/python26/bin”;export PATH
###########################
2)test
[root@devel photo_uw]# python26 Python 2.6.5 (r265:79063, Jul 20 2010, 10:39:03) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
2. PIL
1) install
wget http://effbot.org/downloads/Imaging-1.1.7.tar.gz tar zxvf Imaging-1.1.7.tar.tar cd Imaging-1.1.7 python26 setup.py build_ext -i python26 setup.py install cd ..
[root@devel photo_uw]# python26 Python 2.6.5 (r265:79063, Jul 20 2010, 10:39:03) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import Image >>>
3. setuptools
wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz tar zxvf setuptools-0.6c11.tar.gz cd setuptools-0.6c11 python26 setup.py install cd ..
4. flup
wget http://www.saddi.com/software/flup/dist/flup-1.0.2.tar.gz tar zxvf flup-1.0.2.tar.gz cd flup-1.0.2 python26 setup.py install cd ..
5. MySQL-python
1) install
wget http://nchc.dl.sourceforge.net/project/mysql-python/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz tar zxvf MySQL-python-1.2.3c1.tar.gz cd MySQL-python-1.2.3c1 python26 setup.py build python26 setup.py install cd ..
[root@devel photo_uw]# python26 Python 2.6.5 (r265:79063, Jul 20 2010, 10:39:03) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import MySQLdb >>>
6 Django 1.2.1
1) install
wget http://media.djangoproject.com/releases/1.2/Django-1.2.1.tar.gz tar zxvf Django-1.2.1.tar.gz cp -R Django-1.2.1 /opt/python26 cd /opt/python26/lib/python2.6/site-packages/ ln -s /opt/python26/Django-1.2.1/django django
cd Django-1.2.1 python26 setup.py install
[root@devel photo_uw]# python26 Python 2.6.5 (r265:79063, Jul 20 2010, 10:39:03) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> django.get_version() '1.2.1'
1) install
wget http://pypi.python.org/packages/source/d/django-treebeard/django-treebeard-1.61.tar.gz tar zxvf django-treebeard-1.61.tar.gz cd django-treebeard-1.61 python26 setup.py install
[root@devel photo_uw]# python26 Python 2.6.5 (r265:79063, Jul 20 2010, 10:39:03) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import treebeard >>>
1) nginx
cd /opt/nginx/conf/vhosts vi vhost-www_tech.conf upstream backend_www_tech { #server unix:/var/run/fcgi/www/www_tech.sock; server unix:/var/run/fcgi/www_tech.sock; } server { listen 192.168.0.250; server_name 192.168.0.250; #charset gb2312; access_log /var/log/nginx/www_tech/www_tech_access_log combined; error_log /var/log/nginx/www_tech/www_tech_error_log notice; location / { root /infoware/www_tech/web; #allow all; #fastcgi_pass backend_dorm; fastcgi_pass backend_www_tech; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_pass_header Authorization; include fastcgi_params_django; } location /static { root /infoware/www_tech/web; } error_page 404 http://192.168.0.250/static/error404.htm; }
## 貌似是SCRIPT_NAME所引起的问题,而Django好像使用的是PATH_INFO,为了避免和其他的fcgi冲突,所以新建一个django专用的fastcgi_params_django
## Python2.4 + Django 0.96 版本不需要,因为Django 0.96 还不支持SCRIPT_NAME
## 可以查看django的django\core\handlers目录下的modpython.py 文件
vi /opt/nginx/conf/fastcgi_params_django fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param QUERY_STRING $query_string; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SERVER_PROTOCOL $server_protocol; # fastcgi_param SCRIPT_NAME $fastcgi_script_name; # fastcgi_param REQUEST_URI $request_uri; # fastcgi_param DOCUMENT_URI $document_uri; # fastcgi_param DOCUMENT_ROOT $document_root; 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;
cd /infoware/_conf/www_tech/ vi start_www_tech.sh #!/bin/bash ## start_www_tech.sh: start www_tech app in django fcgi mode ## ljzhou, 2010.08.26 ## TODO # - executed under deamontools(in method=thread mode), to get # (1) controled env (2) 'web' uid (3) monitored process # - dormctl.sh script(nginx+django?), just as apachectl APP_DIR="/infoware/www_tech/web" CFG_DIR="/infoware/_conf/www_tech" PYTHON="/usr/bin/python26" DJANGO_ADMIN="/opt/python26/lib/python2.6/site-packages/django/bin/django-admin.py" #PYTHON="/opt/python/bin/python2" #DJANGO_ADMIN="/usr/lib/python2.4/site-packages/django/bin/django-admin.py" ############### no config below this line ################## export PYTHONPATH="$PYTHONPATH:$CFG_DIR" # mysettings.py in $CFG_DIR #export DJANGO_SETTINGS_MODULE=mysettings export DJANGO_SETTINGS_MODULE=settings umask 027 ## server: self daemonized, total num=20 with 10 threads each ## Help message: help ## TCP socket : host=... port=... PIDFILE="/var/run/fcgi/www_tech.pid" if [ -f $PIDFILE ]; then kill `cat -- $PIDFILE` rm -f -- $PIDFILE sleep 3 fi $PYTHON $DJANGO_ADMIN \ runfcgi daemonize=true method=prefork \ maxspare=5 minspare=2 maxchildren=10 maxrequests=500 \ socket="/var/run/fcgi/www_tech.sock" pidfile=$PIDFILE \ umask=000 debug=true \ --pythonpath=$APP_DIR # EOF: start_www_tech.sh stop script like this , only Remark those: #$PYTHON $DJANGO_ADMIN \ # runfcgi daemonize=true method=prefork \ # maxspare=5 minspare=2 maxchildren=10 maxrequests=500 \ # socket=&"/var/run/fcgi/www_tech.sock" pidfile=$PIDFILE \ # umask=000 debug=true \ # --pythonpath=$APP_DIR from http://tech.foolpig.com/2010/08/30/python-django-nginx/ -----------------------------------------------------------------------------django+uwsgi on nginxI decided to move us to a lighter application server so that we could get the most out of our system resources, and after a lot of research and testing I chose uWSGI. While I was at it, I decided to replace Perlbal and Lighttpd with Nginx because of its great configuration syntax and excellent performance. I also upgraded us to Ubuntu 10.04 and Postgres 8.4. The result was a resounding success! Memory usage and CPU load on each of the web nodes dropped dramatically. Swap usage dropped to almost nothing. The overall responsiveness of the site improved noticeably, and the timeout errors and OGR failures disappeared entirely. If you'd like to give this stack a try, read on for an overview of the setup on Ubuntu 10.04. I'm using the standard Ubuntu source package for Nginx, but modifying it slightly and them installing it with dpkg-buildpackage. This post is just about the setup relevant to Nginx and uWSGI. If you need a more complete server setup guide, try my Provisioning a new server post. uWSGI Before we build Nginx, uWSGI needs to be compiled so that its module can be included in the Nginx build. $ sudo apt-get install build-essential python-dev libxml2-dev $ wget http://projects.unbit.it/downloads/uwsgi-0.9.5.4.tar.gz $ tar -xzf uwsgi-0.9.5.4.tar.gz $ cd uwsgi-0.9.5.4 $ make -f Makefile.Py26 Copy the executable to the local sbin directory. $ sudo cp uwsgi /usr/local/sbin Also, copy the default uwsgi settings to the /etc/nginx directory. $ sudo mkdir /etc/nginx $ sudo cp nginx/uwsgi_params /etc/nginx $ cd .. Nginx We need to slightly modify the nginx package from Ubuntu to add uWSGI (and, optionally, SSL). $ sudo apt-get install libssl-dev $ sudo apt-get build-dep nginx $ apt-get source nginx $ cd nginx-0.7* $ emacs debian/rules Add the following lines to the end of the configure options. Make sure to include backslashes so that all the options are interpreted as being on one line. If you don't need SSL, ignore that line. --with-http_ssl_module \ --add-module=$(CURDIR)/../uwsgi-0.9.5.4/nginx Build, install, and hold the packages. $ dpkg-buildpackage $ cd .. $ sudo dpkg -i nginx*.deb $ echo "nginx hold" | sudo dpkg --set-selections $ echo "nginx-dbg hold" | sudo dpkg --set-selections Starting with nginx-0.8.41, you can add something like --http-uwsgi-temp-path=/var/lib/nginx/uwsgi to the debian/rules so that the temp files are kept in the right place. Until then (probably a later version of Ubuntu), you'll need to create a /usr/local/nginx/uwsgi_temp folder to use for the temp files. $ sudo mkdir -p /usr/local/nginx/uwsgi_temp Supervisor To manage the uWSGI processes, I use Supervisor. In Ubuntu 10.04, you can simply install it with apt-get. $ sudo apt-get install supervisor Configuration Supervisor To configure uWSGI, I use command-line options in my Supervisor config. The example below is similar to what I use in production for Pegasus, but you'll want to take a look at the uWSGI docs and tweak for your situation. [program:myapp] command=/usr/local/sbin/uwsgi --home /home/myuser/.virtualenvs/myapp/ --module myapp.deploy.wsgi --socket 10.1.2.3:10000 --pythonpath /sites/myapp.com/code/myapp --processes 5 --master --harakiri 120 --max-requests 5000 directory=/sites/myapp.com/code/myapp environment=DJANGO_SETTINGS_MODULE='myapp.settings' user=www-data autostart=true autorestart=true stdout_logfile=/sites/myapp.com/logs/uwsgi.log redirect_stderr=true stopsignal=QUIT The module I specify in the --module option simply contains: import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() The IP address in the --socket option is the server's IP address on the interface reserved for local network traffic. On Rackspace, eth1 is your local interface. Use the ifconfig command to find your IP address on the local interface. If you're just using uWSGI on localhost, you can use something like --socket /sites/myapp.com/var/run/myapp.sock instead to avoid the overhead of the full TCP stack. My value for --harakiri is rather high, and my value for --max-requests is rather low. You may not even need either of these options, but I'm using them to solve some problems specific to Pegasus. Nginx For the site-specific Nginx config, I'm using something like this: upstream myapp { server 10.1.2.3:10000; server 10.1.2.4:10000; server 10.1.2.5:10000; } server { listen 80; listen 443; server_name myapp.com www.myapp.com; access_log /sites/myapp.com/logs/nginx-access.log; error_log /sites/myapp.com/logs/nginx-error.log; root /sites/myapp.com/public; ssl_certificate /sites/myapp.com/ssl/myapp.crt; ssl_certificate_key /sites/myapp.com/ssl/myapp.key; location / { # This checks for a file called simply "downtime" in the public # directory, and puts up the downtime page if it exists. if (-f /sites/myapp.com/public/downtime) { return 503; } uwsgi_pass myapp; include uwsgi_params; } location /media { # This makes static media available at the /media/ url. The # media will continue to be available during site downtime, # allowing you to use styles and images in your maintenance page. alias /sites/myapp.com/public/media; } error_page 502 503 504 @maintenance; location @maintenance { # In this example, there's a directory in the site media files # called "downtime" that contains a "maintenance.html" file and # any styles and images needed for the maintenance page. root /sites/myapp.com/public/media/downtime; rewrite ^(.*)$ /maintenance.html break; } } If you're just using uWSGI on localhost, then skip the upstream section and use something like uwsgi_pass unix:///sites/myapp.com/var/run/myapp.sock; in the root location definition instead. Firing it up Restart Supervisor with sudo /etc/init.d/supervisor restart, and it should reload the config and bring the uWSGI processes up. Restart Nginx with sudo /etc/init.d/nginx restart, and you should now be able to reach your site. If not, take a look at the logs and start troubleshooting. from http://brandonkonkle.com/blog/2010/sep/14/django-uwsgi-and-nginx/ ---------------------------------------------------------------------------------------Provisioning a new Ubuntu server for Django
I've been a long-time satisfied user of Webfaction, but recently I've had a strong urge to move to VPS hosting so that I can have greater control over the environment. After some research, I went with Rackspace Cloud because of the incredibly cheap low-end options. My site doesn't use a huge amount of bandwidth, so Rackspace looks to be the most feature-packed and still cost-effective option. A friend of mine, Kevin Whitaker, recently posted a great article about getting up and running with Django in a server environment for testing or production. He used Ubuntu, Postgres, Nginx, and FastCGI to make up his stack. I've never set up Nginx before, so his post was a great help in getting Nginx configured. My stack is slightly different, however, since I prefer to use Gunicorn instead of FastCGI and I use supervisord to manage my processes. I also use virtualenv to manage dependencies like Django itself and psycopg2. I'm including my install notes below so that I can provide a complete picture of one way of provisioning a new server from build to deploy. My site is relatively low-traffic, so I'm not going to go into postgres tweaking, connection pooling, caching, etc. I'll save those topics for another post. These notes were made on a Rackspace Cloud instance, but they should apply to a variety of other VPS hosts with only minor modifications. If you've got tips on things that need to be changed for other providers, let me know and I'll edit the post. I want this to stay up to date for awhile.After the build is complete
Configuration
My first step was to log into my new instance using SSH. You should get an email from Rackspace with the IP address and root password.I then installed my preferred editor - obviously an optional step.$ ssh root@123.45.67.890 root@123.45.67.890's password: Welcome to Ubuntu!Then I used visudo to set up sudo access the way I like it.$ apt-get install emacs23-nox $ export EDITOR=emacsUnder this line:$ visudoI added the following lines to preserve my editor and Django environment settings:Defaults env_resetThen I changed this line:Defaults env_keep += "EDITOR VISUAL" Defaults env_keep += "DJANGO_SETTINGS_MODULE PYTHONPATH"To:%sudo ALL=(ALL) ALLThis allows users with the group%admin ALL=(ALL) ALLadminto use sudo for all commands. Then I added my first user and group. I typically prefer to use a separate user account for each developer or administrator that will be accessing the box, and add them to appropriate groups for access.Then I switched to my new user, and added my public key so that I can SSH without requiring a password. If you're not familiar with this, the guide at Github is quick and to the point.$ adduser myuser $ addgroup admin $ adduser myuser adminThen, I logged out and made sure I can SSH in using the new user with no problems. Once that's done, I locked down the root account for security (probably because I'm a long time Ubuntu user and it just feels wrong any other way).$ su - myuser $ mkdir .ssh $ cd .ssh $ wget http://mydomain.com/path/to/my/pubkey/id_rsa.pub $ mv id_rsa.pub authorized_keysI also make my editor choice permanent.$ sudo passwd -l root$ sudo update-alternatives --config editorNginx
With that taken care of, I was ready to install Nginx.I used this Slicehost article to learn about the basic nginx conf options.$ sudo apt-get install nginx $ sudo /etc/init.d/nginx start $ sudo emacs /etc/nginx/nginx.confPostgres
Then I installed postgres. I first changed the password on the postgres user for security.Then I set up a new user to use for my site.$ sudo apt-get install postgresql $ sudo passwd postgres $ sudo -u postgres psql postgres=# \password postgres postgres=# \qI use a Unix domain socket for my postgres connection, so I have to edit pg_hba.conf to allow md5 login from domain sockets.$ sudo -u postgres createuser myproject $ sudo -u postgres psql postgres=# \password myproject postgres=# \qI change the lines that say:$ sudo emacs /etc/postgresql/8.4/main/pg_hba.confTo:# "local" is for Unix domain socket connections only local all all identThen:# "local" is for Unix domain socket connections only local all all md5$ sudo /etc/init.d/postgresql-8.4 restart(Substitute your favorite VCS here)
Now for my VCS. I use the Git PPA.$ sudo apt-get install python-software-properties $ sudo add-apt-repository ppa:git-core/ppa $ sudo apt-get update $ sudo apt-get install git-coreSetting up a Django site
Setting up the structure
First, I pulled over my git repositories. I use the/codedirectory for hosting the master copies of my repositories to use as a hub. I keep the live checkouts in/sites/mydomain.com/code/.$ sudo mkdir /code $ sudo chown myuser:admin /code $ cd /code $ git clone --mirror olddomain.com:/code/repository_name.git $ sudo mkdir /sites $ sudo chown myuser:admin /sites $ cd /sites $ mkdir -p mydomain.com/{code,public,logs,backup} $ cd mydomain.com $ sudo chown :www-data logs public $ sudo chmod g+w logs public $ git clone /code/repository_name.git code/ Initialized empty Git repository in /sites/mydomain.com/code/.git/Media
I set up the media and made sure www-data could access it and write to the root directory.Then I synced the media from my old server, so that user-created media wouldn't be lost.$ cd public $ ln -s ../code/projectname/media $ sudo chown :www-data media $ sudo chmod g+w media$ rsync -avz --progress old.domain.com:~/path/to/media/ media/Restoring the database
The next step was backing up and restoring the database.$ ssh old.domain.com $ pg_dump dbname | bzip2 > dbname.`date +%Y%m%dT%H%M%S`.sql.bz2 $ exit $ ssh new.domain.com $ cd /sites/mydomain.com/backup/ $ scp old.domain.com:~/dnmame.<timestamp>.sql.bz2 ./ $ sudo su postgres $ createdb dbname $ bzcat dnmame.<timestamp>.sql.bz2 | psql dbname $ psql dbname postgres=# GRANT ALL ON DATABASE dbname TO myproject; postgres=# \q $ exitInstalling dependencies
I then created my virtualenv and installed my dependencies.At the bottom of .bashrc:$ sudo apt-get install build-essential python-dev libpq-dev $ sudo apt-get install python-setuptools $ sudo easy_install -U pip $ sudo pip install virtualenv $ sudo pip install virtualenvwrapper $ mkdir /sites/.virtualenvs $ emacs ~/.bashrcThen, back in the shell:export WORKON_HOME=/sites/.virtualenvs source /usr/local/bin/virtualenvwrapper.shPIL is a tough one. I usually just install it globally. Since I install my virtualenv's with --no-site-packages, I need to symlink PIL into the site-packages.$ . ~/.bashrc $ mkvirtualenv projectname $ workon projectname $ pip install -r /sites/mydomain.com/code/requirements.txt $ deactivateThen, I edited my project's settings.py to reflect the new environment setup. Finally, I added ntpdate to keep my server-s clock in sync.$ sudo apt-get install python-imaging $ workon projectname $ cdsitepackages $ ln -s /usr/lib/python2.6/dist-packages/PIL $ ln -s /usr/lib/python2.6/dist-packages/PIL.pth$ sudo dpkg-reconfigure tzdata $ sudo apt-get install ntpdate $ sudo crontab -e 30 23 * * * /usr/sbin/ntpdate ntp.ubuntu.com > /dev/nullNginx
I added an nginx.conf to my source control.The Nginx conf:$ emacs /sites/mydomain.com/code/deploy/nginx.confI then symlinked it intoserver { listen 80; server_name www.mydomain.com; rewrite ^/(.*) http://mydomain.com/$1 permanent; } server { listen 80; server_name mydomain.com; access_log /sites/mydomain.com/logs/access.log; error_log /sites/mydomain.com/logs/error.log; location /media { root /sites/mydomain.com/public; } location / { proxy_pass http://127.0.0.1:29000; } }/etc/nginx/sites-available/andsites-enabled/.$ sudo ln -s /sites/mydomain.com/code/deploy/nginx.conf /etc/nginx/sites-available/mydomain.com $ sudo ln -s /etc/nginx/sites-available/mydomain.com /etc/nginx/sites-enabled/mydomain.com $ sudo /etc/init.d/nginx restartGunicorn
Gunicorn should be installed in your virtualenv as part of your requirements.txt. If you're not using virtualenv and pip, or zc.buildout, then you should definitely read up on them. They are a vital part of any serious Django stack.I already had a simple Gunicorn conf in my source control, which I simply modified for the new environment.$ emacs /sites/mydomain.com/code/deploy/gunicorn.conf.pybind = "127.0.0.1:29000" logfile = "/sites/mydomain.com/logs/gunicorn.log" workers = 3Supervisord
Here's a basic config file:$ sudo pip install supervisor $ sudo emacs /etc/supervisord.confThen I created an init.d script:[unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) [supervisord] logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket [program:myproject] command=/sites/.virtualenvs/myproject/bin/gunicorn_django -c deploy/gunicorn.conf.py directory=/sites/mydomain.com/code user=www-data autostart=true autorestart=true stdout_logfile=/sites/mydomain.com/logs/supervisord.log redirect_stderr=trueHere's what I used:$ sudo emacs /etc/init.d/supervisordThen I finished up the init.d script.# Supervisord auto-start # # description: Auto-starts supervisord # processname: supervisord # pidfile: /var/run/supervisord.pid SUPERVISORD=/usr/local/bin/supervisord SUPERVISORCTL=/usr/local/bin/supervisorctl case $1 in start) echo -n "Starting supervisord: " $SUPERVISORD echo ;; stop) echo -n "Stopping supervisord: " $SUPERVISORCTL shutdown echo ;; restart) echo -n "Stopping supervisord: " $SUPERVISORCTL shutdown echo echo -n "Starting supervisord: " $SUPERVISORD echo ;; esacIf all goes well, you can check the status on your site.$ sudo chmod +x /etc/init.d/supervisord $ sudo update-rc.d supervisord defaults $ sudo /etc/init.d/supervisord startYou can also grep for the gunicorn processes.$ sudo supervisorctl status myproject RUNNING pid 11616, uptime 0:00:03$ ps -ef | grep gunicornTesting
To test this new setup, you can add domain name overrides to the /etc/hosts file on your local machine.Now you can go to your browser and access# Do this on your local machine - not your server $ sudo emacs /etc/hosts 123.45.67.890 mydomain.commydomain.com. You should see your site. To restart your site, use:Make sure to change your /etc/hosts back. from http://brandonkonkle.com/blog/2010/jun/25/provisioning-new-ubuntu-server-django/$ sudo supervisorctl restart myproject
No comments:
Post a Comment