Serve django application with Apache and mod_wsgi on CentOS

在apache上配置mod_wsgi 来部署dango折腾了我不少时间,看了Google找到的各种中英文文档,博客。由于不同配置环境,不要盲目照抄。
一开始装了mod_python 才发现过时了,果断放弃。接下来记述下我配置的过程,有什么问题欢迎交流。

环境:

我用的 lamp 一键安装包 https://github.com/teddysun/lamp
Django 版本
>>> import django
>>> print (django.VERSION)
(1, 8, 2, ‘final’, 0)
>>>
python 版本
# python -V
Python 2.7.10
Apache 版本
# httpd -v
Server version: Apache/2.4.10 (Unix)
Server built: Sep 17 2014 10:31:34

CentOS 版本
# cat /etc/redhat-release
CentOS release 6.7 (Final)

我在 /usr/local 创建了一个项目 sky
# django-admin.py startproject sky
修改sky/sky/wsgi.py

import os,sys
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sky.settings")
sys.path.append(r'/usr/local/sky')
application = get_wsgi_application()

找到Apache配置文件
find / -name httpd.conf
/usr/local/apache/conf/original/httpd.conf
/usr/local/apache/conf/httpd.conf

ps: 别忘了LoadModule
httpd.conf 里面添加
#load module mod_wsgi.so
LoadModule wsgi_module modules/mod_wsgi.so

修改httpd.conf
vim /usr/local/apache/conf/httpd.conf

文件最后添加如下

 <VirtualHost *:80>
     DocumentRoot "/usr/local/sky"
     WSGIScriptAlias / "/usr/local/sky/sky/wsgi.py"
     Alias /static/ /root/static/ 
     ServerName search.skywhat.com
 </VirtualHost>

注意:这里static静态文件,

我在sky/settings.py 中添加了STATIC_ROOT=”/root/static/”

然后 python manage.py collectstatic

django会将所有静态文件收集到我设置的/root/static/  中,所以配置文件httpd.conf 需要添加

 Alias /static/ /root/static/

不然加载不出来的,这里我一开始疑惑了很久。

看,这就是collectstatic 以后的static结构

[root@li671-220 ~]# tree static/
static/
└── admin
├── css
│   ├── base.css
│   ├── changelists.css
│   ├── dashboard.css
│   ├── forms.css
│   ├── ie.css
│   ├── login.css
│   ├── rtl.css
│   └── widgets.css
├── img
│   ├── changelist-bg.gif
│   ├── changelist-bg_rtl.gif
│   ├── default-bg.gif
│   ├── default-bg-reverse.gif
│   ├── deleted-overlay.gif
│   ├── gis
│   │   ├── move_vertex_off.png
│   │   └── move_vertex_on.png
│   ├── icon_addlink.gif
│   ├── icon_alert.gif
│   ├── icon_calendar.gif
│   ├── icon_changelink.gif
│   ├── icon_clock.gif
│   ├── icon_deletelink.gif
│   ├── icon_error.gif
│   ├── icon-no.gif
│   ├── icon_searchbox.png
│   ├── icon_success.gif
│   ├── icon-unknown.gif
│   ├── icon-yes.gif
│   ├── inline-delete-8bit.png
│   ├── inline-delete.png
│   ├── inline-restore-8bit.png
│   ├── inline-restore.png
│   ├── inline-splitter-bg.gif
│   ├── nav-bg.gif
│   ├── nav-bg-grabber.gif
│   ├── nav-bg-reverse.gif
│   ├── nav-bg-selected.gif
│   ├── selector-icons.gif
│   ├── selector-search.gif
│   ├── sorting-icons.gif
│   ├── tooltag-add.png
│   └── tooltag-arrowright.png
└── js
├── actions.js
├── actions.min.js
├── admin
│   ├── DateTimeShortcuts.js
│   └── RelatedObjectLookups.js
├── calendar.js
├── collapse.js
├── collapse.min.js
├── core.js
├── inlines.js
├── inlines.min.js
├── jquery.init.js
├── jquery.js
├── jquery.min.js
├── LICENSE-JQUERY.txt
├── prepopulate.js
├── prepopulate.min.js
├── related-widget-wrapper.js
├── SelectBox.js
├── SelectFilter2.js
├── timeparse.js
└── urlify.js

6 directories, 62 files

DocumentRoot 为项目目录
WSGI后面两个参数 一个 / 一个 /usr/local/sky/sky/wsgi.py
ServerName 为我的二级域名

ps: 这里 我在DNS解析里,把search.skywhat.com 解析到了我的网站 IP 上

重启Apache
# apachectl restart

访问 search.skywhat.com

It worked!
Congratulations on your first Django-powered page.

Of course, you haven’t actually done any work yet. Next, start your first app by running python manage.py startapp [app_label].
You’re seeing this message because you have DEBUG = True in your Django settings file and you haven’t configured any URLs. Get to work!

当然,我这里写的很一帆风顺。但是我第一配置的时候是遇到很多杂七杂八的问题。
我的Evernote 笔记,记录了一些StackOverflow的细节问题。
https://www.evernote.com/l/AiGTZk3BQr5EyYe-f2PM9TQqj67yA42iVbo

访问django做出来的页面时候,总是会出现 Internal Server Error

找到的原因是需要在settings.py 更改ALLOWED_HOSTS配置

In your settings.py make sure you have set the variable ALLOWED_HOSTS to include the name of your domain. If not you’ll get a 500 error whenever the variable DEBUG is set to False. For example:

ALLOWED_HOSTS = ['mydomain.com']

https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts

Using my Django app, I’m able to read from the database just fine. When the application didn’t have permission to access the file, it gave me this error:

attempt to write a readonly database

Which made sense. So I edited the permissions on the file, so that the Apache process had write permissions. However, instead of it being able to write, I get this cryptic error:

unable to open database file

If it’s useful, here’s the entire output:

Request Method: POST
Request URL:    http://home-sv-1/hellodjango1/polls/1/vote/
Exception Type: OperationalError
Exception Value:    
unable to open database file
Exception Location: /usr/lib/pymodules/python2.5/django/db/backends/sqlite3/base.py in execute, line 193
Python Executable:  /usr/bin/python
Python Version: 2.5.2
Python Path:   
 ['/var/www', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', 
'/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages',
 '/usr/lib/pymodules/python2.5', '/usr/lib/pymodules/python2.5/gtk-2.0']
Server time:    Sun, 23 Aug 2009 07:06:08 -0500


Let me know if a stack trace is necessary.

asked Aug 23 ’09 at 12:08
nbolton
2,10783552

7 Answers

Aha, just stumbled across an article explaining this. Also Django have info on theirNewbieMistakes page.

The solution is to make sure the directory containing the database file also has write access allowed to the process.

In my case, running this command fixed the problem:

chown www-data. .


answered Aug 23 ’09 at 12:14
nbolton
2,10783552
1
This assumes you’re on debian/ubuntu, if you’re using CentOS you’re going to want to use ‘apache’ instead of ‘www-data’ – Luke Chadwick May 23 ’13 at 6:44
1
@nbolton Note: chown www-data. . should actually be chown www-data . otherwise there is some wizardy of chown command that I don’t know about… please enlighten me. – Jeff Sheffield Aug 19 ’14 at 18:13
1
I believe the extra dot is to set the group to the owner’s default group. Otherwise it doesn’t change the group. This is just from memory though, I highly recommend you try that out yourself. – nbolton Feb 26 at 11:55
Summarized here in case of future link rot or tl;dr: SQLite3 wants write access to the DB file’s directory so that it can create a journal file there when a transaction is opened. – user1454265 Jul 23 at 16:04
Great for Linux users. Bupkiss for Windows. – Jay Blanchard Aug 17 at 16:46
 

27down voteaccepted

Figured it out. I had an apache config error on this line:

Alias /static/ /home/daifotis/code/feris/sitestatic

I should have written static without the trailing slash. With the trailing slash Apache will not expand the URL path.

Alias /static /home/daifotis/code/feris/sitestatic

发表评论

电子邮件地址不会被公开。 必填项已用*标注