Linux下将Python的Django项目部署到Apache服务器


Posted in Python onDecember 24, 2015

这几天花了点时间,将把django开发好的web项目部署到Apache上,参考了官方的一些文档和互联网上的文档,还是花了比较多的时间,这里把配置的过程说一下。
方便有需要的朋友,可以参考,少走弯路!
1. django项目部署环境说明
操作系统 : Red Hat Enterprise Linux Server release 5.3 (Tikanga) x86_64
apache版本 : httpd-2.2.3-22.el5
mod_wsgi版本 : mod_wsgi-3.2-1.el5 fedora epel可以下载
Django版本 : 1.2.3
python 版本 : 2.5
这里假定Django和Apache已经安装好,并且Django的项目已经开发好。
以上软件包都是通过yum包安装,软件包都是系统标准目录结构!
django开发好的项目目录是 /var/www/html/server,项目目录结构如下(标准django项目目录结构)

#tree -d server/
 server/
 |-- __init__.py
 |-- manage.py
 |-- settings.py
 |-- backend
 |-- static
 |  |-- images
 |  |-- locale
 |  |-- plugins
 |  `-- themes
 |    |-- default
 |    |  `-- images
 |    |-- gray
 |    |  `-- images
 |    `-- icons
 |-- template
 `-- view

2. Apache和mod_wsgi配置
修改wsgi配置(/etc/httpd/conf.d/wsgi.conf)

#cat /etc/httpd/conf.d/wsgi.conf 
 LoadModule wsgi_module modules/mod_wsgi.so
 WSGIScriptAlias / "/var/www/html/server/django.wsgi"
 
 <Directory "/var/www/html/server">
  Order Deny,Allow
  Allow from all
 </Directory>

项目目录中的django.wsgi这个文件是需要新建的,后面会说到如何新建这个文件。
apache使用的标准配置,Apache的DocumentRoot 指向的是 /var/www/html 目录
3. 新建django.wsgi文件
在项目目录/var/www/html/server下新建一个django.wsgi,文件内容如下:

#cat /var/www/html/server/django.wsgi
 # -*- coding: utf-8 -*-
 import os
 import sys
 os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
 os.environ['PYTHON_EGG_CACHE'] = '/tmp/.python-eggs'
 current_dir = os.path.dirname(__file__)
 if current_dir not in sys.path: sys.path.append(current_dir) 
 import django.core.handlers.wsgi
 application = django.core.handlers.wsgi.WSGIHandler()

 
第三行 os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' ,这个settings就是指项目目录下的setting.py文件.
第四行 os.environ['PYTHON_EGG_CACHE'] = '/tmp/.python-eggs' ,指定解压egg文件的cache目录,确保运行apache的用户,能够对此目录有读写权限.
第五,六行 将当前目录自动加入到python的搜索路径,如果项目中有自己写的模块,方便使用和发布

最后,这个django.wsgi文件名可以随便取,例如test.wsgi、app.wsgi等等,但是一定要与/etc/httpd/conf.d/wsgi.conf配置文件中配置保持一致。
如果您这里新建的文件名不是django.wsgi而是test.wsgi,那么/etc/httpd/conf.d/wsgi.conf中的配置就应该修改为

WSGIScriptAlias / "/var/www/html/server/test.wsgi"

4. 修改django项目中的setting.py文件
找到项目目录下的setting.py,对于这里就是/var/www/html/server/setting.py。找到其中的TEMPLATE_DIRS,修改为:

TEMPLATE_DIRS = ("/var/www/html/server/template",)

注意: 模板目录在这里一定要用绝对路劲,而不能用相对路径,当然也有方法动态设置模板路劲

PS:关于mod_wsgi
目前mod_wsgi有两种工作模式:

第一种是嵌入模式,类似于mod_python,直接在apache进程中运行,这样的好处是不需要另外增加进程,但是坏处也很明显,所有内存都和apache共享,如果和mod_python一样造成内存漏洞的话,就会危害整个apache。而且如果apache是用worker mpm,mod_wsgi也就强制进入了线程模式,这样子对于非线程安全的程序来说就没法用了。

这种模式下需要在apache的vhost中如下设置:

<span style="font-family: 'times new roman', times;">WSGIScriptAlias /path /path-to-wsgi</span>

即可生效,对于小型脚本的话,直接用这种模式即可。

第二种是后台模式,类似于FastCGI的后台,mod_wsgi会借apache的外壳,另外启动一个或多个进程,然后通过socket通信和apache的进程联系。

这种方式只要使用以下配置即可:

#启动WSGI后台,site1是后台名字


WSGIDaemonProcess site1 processes=1 threads=15 display-name=%{GROUP}

#分配当前上下文应该使用哪个WSGI后台,可以放在Location里面指定
WSGIProcessGroup site1

#根据当前上下文的ProcessGroup分配到对应的后台
WSGIScriptAlias /path /path-to-wsgi

在这种模式下,我们可以通过调节processes和threads的值来设置三种MPM的模式:prefork', 'worker', 'winnt'。

winnt模式

WSGIDaemonProcess example threads=25
wsgi.multithread True
wsgi.multiprocess False

此时processes=1,但是multiprocess为false

如果显式地指出processes为1那么:

WSGIDaemonProcess example processes=1 threads=25
wsgi.multithread True
wsgi.multiprocess True

worker模式

WSGIDaemonProcess example processes=2 threads=25

wsgi.multithread True
wsgi.multiprocess True

preforker模式

WSGIDaemonProcess example processes=5 threads=1
wsgi.multithread False
wsgi.multiprocess True

 

后台模式由于是与apache进程分离了,内存独立,而且可以独立重启,不会影响apache的进程,如果你有多个项目(django),可以选择建立多个后台或者共同使用一个后台。

比如在同一个VirtualHost里面,不同的path对应不同的django项目,可以同时使用一个Daemon:

<span style="font-family: 'times new roman', times;">WSGIDaemonProcess default processes=1 threads=1 display-name=%{GROUP}
 
WSGIProcessGroup default
 
WSGIScriptAlias /project1 “/home/website/project1.wsgi”
 
WSGIScriptAlias /project2 “/home/website/project2.wsgi”</span>

这样子两个django都使用同一个WSGI后台。

也可以把不同的项目分开,分开使用不同的后台,这样开销比较大,但就不会耦合在一起了。

display-name是后台进程的名字,这样方便重启对应的进程,而不需要全部杀掉。

<span style="font-family: 'times new roman', times;">WSGIDaemonProcess site1 processes=1 threads=1 display-name=%{GROUP}
 
WSGIDaemonProcess site2 processes=1 threads=1 display-name=%{GROUP}
 
<Location “/project1″>
WSGIProcessGroup site1
</Location>
WSGIScriptAlias /project1 “/home/website/project1.wsgi”
 
<Location “/project1″>
WSGIProcessGroup site2
</Location>
WSGIScriptAlias /project2 “/home/website/project2.wsgi”</span>

 
对于django 1.0以下的版本,由于官方认定不是线程安全的,所以建议使用多进程单线程模式

processes=n threads=1

对于django 1.0以后,就可以放心的使用多进程多线程模式:

processes=2 threads=64

这样子性能会更好。

Python 相关文章推荐
python抓取网页内容示例分享
Feb 24 Python
python 打印出所有的对象/模块的属性(实例代码)
Sep 11 Python
对python使用http、https代理的实例讲解
May 07 Python
利用Python如何将数据写到CSV文件中
Jun 05 Python
Python模拟简单电梯调度算法示例
Aug 20 Python
Python装饰器基础概念与用法详解
Dec 22 Python
python代码实现逻辑回归logistic原理
Aug 07 Python
Django-Scrapy生成后端json接口的方法示例
Oct 06 Python
Python高阶函数与装饰器函数的深入讲解
Nov 10 Python
Python之qq自动发消息的示例代码
Feb 18 Python
基于Python的EasyGUI学习实践
May 07 Python
Python+Appium实现自动抢微信红包
May 21 Python
在Linux系统上部署Apache+Python+Django+MySQL环境
Dec 24 #Python
在Mac OS上使用mod_wsgi连接Python与Apache服务器
Dec 24 #Python
在Mac OS上搭建Python的开发环境
Dec 24 #Python
详解Python字符串对象的实现
Dec 24 #Python
浅谈Python单向链表的实现
Dec 24 #Python
Python使用面向对象方式创建线程实现12306售票系统
Dec 24 #Python
安装ElasticSearch搜索工具并配置Python驱动的方法
Dec 22 #Python
You might like
php 面试碰到过的问题 在此做下记录
2011/06/09 PHP
php使用mkdir创建多级目录入门例子
2014/05/10 PHP
destoon找回管理员密码的方法
2014/06/21 PHP
php抓取并保存网站图片的实现代码
2015/10/28 PHP
php命令行模式代码实例详解
2021/02/26 PHP
非常好的js代码
2006/06/27 Javascript
JS实现距离上次刷新已过多少秒示例
2014/05/23 Javascript
购物车前端开发(jQuery和bootstrap3)
2016/08/27 Javascript
js实现城市级联菜单的2种方法
2017/06/23 Javascript
理解javascript async的用法
2017/08/22 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
node之本地服务器图片上传的方法示例
2019/03/26 Javascript
微信小程序云开发之使用云存储
2019/05/17 Javascript
node实现socket链接与GPRS进行通信的方法
2019/05/20 Javascript
深入浅析JavaScript中的in关键字和for-in循环
2020/04/20 Javascript
Python常用内置模块之xml模块(详解)
2017/05/23 Python
windows下添加Python环境变量的方法汇总
2018/05/14 Python
Python 使用Numpy对矩阵进行转置的方法
2019/01/28 Python
python实现点击按钮修改数据的方法
2019/07/17 Python
对django 模型 unique together的示例讲解
2019/08/06 Python
解析Tensorflow之MNIST的使用
2020/06/30 Python
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
Styleonme中文网:韩国高档人气品牌
2017/06/21 全球购物
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
店面销售职位的职责
2014/03/09 职场文书
商铺租赁意向书
2014/04/01 职场文书
中秋寄语大全
2014/04/11 职场文书
新学期国旗下演讲稿
2014/05/08 职场文书
小学生运动会报道稿
2014/09/12 职场文书
三方股份合作协议书
2014/10/13 职场文书
武夷山导游词
2015/02/03 职场文书
校园歌手大赛主持词
2015/07/03 职场文书
教师培训简讯
2015/07/20 职场文书
2016护理专业求职自荐书
2016/01/28 职场文书
八年级历史教学反思
2016/02/19 职场文书
请求模块urllib之PYTHON爬虫的基本使用
2022/04/08 Python