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抓取网页图片并放到指定文件夹
Apr 24 Python
基于Python实现的ID3决策树功能示例
Jan 02 Python
python批量替换多文件字符串问题详解
Apr 22 Python
django 发送邮件和缓存的实现代码
Jul 18 Python
python生成以及打开json、csv和txt文件的实例
Nov 16 Python
Python OpenCV之图片缩放的实现(cv2.resize)
Jun 28 Python
Python之time模块的时间戳,时间字符串格式化与转换方法(13位时间戳)
Aug 12 Python
python tkinter控件布局项目实例
Nov 04 Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
May 26 Python
Python爬虫之Selenium中frame/iframe表单嵌套页面
Dec 04 Python
python爬虫今日热榜数据到txt文件的源码
Feb 23 Python
python数据处理之Pandas类型转换
Apr 28 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函数
2010/02/16 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
php面试实现反射注入的详细方法
2019/09/30 PHP
用JS操作FRAME中的IFRAME及其内容的实现代码
2008/07/26 Javascript
jquery实现表格隔行换色效果
2015/11/19 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
用NodeJS实现批量查询地理位置的经纬度接口
2016/08/16 NodeJs
AngularJS中transclude用法详解
2016/11/03 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
vue之父子组件间通信实例讲解(props、$ref、$emit)
2018/05/22 Javascript
7个好用的JavaScript技巧分享(译)
2019/05/07 Javascript
React精髓!一篇全概括小结(急速)
2019/05/23 Javascript
[01:31]DOTA2上海特级锦标赛 SECRET战队完整宣传片
2016/03/16 DOTA
在Python的列表中利用remove()方法删除元素的教程
2015/05/21 Python
Python递归函数定义与用法示例
2017/06/02 Python
Python3.5实现的罗马数字转换成整数功能示例
2019/02/25 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
2020/05/25 Python
Python利用socket模块开发简单的端口扫描工具的实现
2021/01/27 Python
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
写给女朋友的道歉信
2014/01/12 职场文书
优秀交警事迹材料
2014/01/26 职场文书
恐龙的灭绝教学反思
2014/02/12 职场文书
加多宝凉茶广告词
2014/03/18 职场文书
人口与计划生育目标管理责任书
2014/07/29 职场文书
组工干部对照检查材料
2014/08/25 职场文书
武当山导游词
2015/02/03 职场文书
幼儿园中秋节活动总结
2015/03/23 职场文书
结婚喜宴祝酒词
2015/08/10 职场文书
2016同学毕业寄语大全
2015/12/04 职场文书
Pytest中skip skipif跳过用例详解
2021/06/30 Python
Win Server2016远程桌面如何允许多用户同时登录
2022/06/10 Servers