几个月前写过一篇《在Dotcloud上架设Django网站》的文章,有读者将自己遇到的问题留在评论里,也有通过Gtalk联系我进行讨论的同学,在大家的帮助下解决了不少问题,现一并整理在这此。
关于404错误
这里说的是服务器(在Dotcloud上一般是nginx)的404错误,Django返回的404错误会有详细的提示,不在讨论范围内。服务器404错误通常——当然也有例外——是Dotcloud设置不当引起的。最常见的是三种情况:
1.目录结构错误
最简单,但可运行的目录结构如下,dmyz是Django项目目录,其他的是配置文件,他们都在dmyz-on-dotcloud之下。
dmyz-on-dotcloud/
├── dmyz
│ ├── __init__.py
│ ├── manage.py
│ ├── settings.py
│ └── urls.py
├── dotcloud.yml
├── requirements.txt
└── wsgi.py
2.wsgi.py文件错误
基本的wsgi.py文件写法如下:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'dmyz.settings' #项目名
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
唯一可能出错的就是项目名了,也就是第2行,这里的’dmyz.settings’应该是Django项目文件夹的名称,比如你的Django项目名为abc,那这里就设置成’abc.settings’。
3.文件错误
这倒是很偶然碰到的,某同学(因为觉得这事太丢人了所以当事人强烈要求隐藏真实姓名)出现了404错误一直找不到问题所在,后来才发现是settings文件某行少了一个逗号,因为它在本机运行和在Dotcloud运行会调用不同的settings文件,所以没发现这个错误。这也说明,如果settings文件错误同样会引发404错误。不过只要能在本机先检查一次,这个问题完全是可以避免的。
4.环境变量问题
具体见本文评论。在dotcloud上运行时,加入sys.path中的目录是dmyz-on-dotcloud而不是dmyz,所以如果在INSTALLED_APPS或是其他引用模块的场合(比如from account import view需要改成 form dmyz.account import view),不加上项目名的话,也会导致404错误,比较好的解决方案是将当前项目文件夹添加到PYTHONPATH变量,在settings.py文件里加入以下代码:
PROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
if PROJECT_DIR not in sys.path:
sys.path.append(PROJECT_DIR)
静态文件和数据库文件问题
在不进行特别的settings文件设置的情况下,静态文件夹和数据库文件要和Django项目文件夹放在同一级目录下:
dmyz-on-dotcloud/
├── dmyz
│ ├── __init__.py
│ ├── manage.py
│ ├── settings.py
│ └── urls.py
├── dev.db #sqlite数据库文件
├── dotcloud.yml
├── requirements.txt
├── static #静态文件夹
│ ├── css
│ ├── images
│ └── js
└── wsgi.py
如果一定要把dev.db文件放到Django项目目录下,也可以修改settings文件。
#当dev.db文件在Django项目目录下
import os
PROJECT_PATH = os.path.dirname(__file__)
PROJECT_NAME = os.path.basename(PROJECT_PATH)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_PATH,'dev.db'),
……
}
}
当修改数据库文件,不能使用 dotcloud push dev.db 来更新,否则会报错 error: The application name “dev.db” is invalid. 。dotcloud虽然和git很像但毕竟不是git,只要用它的dotcloud push dmyz 命令就可以把dmyz-on-dotcloud里的内容都上传了。
但无论我怎么修改STATIC_ROOT/STATICFILES_DIRS,它都会无视Django项目目录和App目录下的static文件夹,所以没有找到把static文件夹也放到Django项目目录下的方法。虽然也可以用postinstall运行collectstatic命令转移static文件夹,但还是多走了一步,如果各位找到很好的设置方法请分享一下吧=)
域名设置
首先利用alias命令绑定域名:
$ dotcloud url dmyz.www
www: http://54bbccc9.dotcloud.com/
www: http://dot.dmyz.org/
然后解析域名,创建一条CNAME记录到gateway.dotcloud.com就可以了。
但要注意的是,alias命令不能绑定空域名,也就是说不能直接绑定 dmyz.org。我们也不能直接做一个CNAME,将dmyz.org转到www.dmyz.org,这就是很常见的域名www解析问题了,因为很常见,所以有很多解决方案,偷懒的做法是直接把dmyz.org做一个A记录到174.129.25.170,这样当用户访问dmyz.org时,它就会自动跳转到www.dmyz.org。
收费问题
之前Dotcloud打出99$/月的价格,导致大多数人都对它没了兴趣。其实如果你不需要绑定自己的域名,免费版相比专业版,只是没有足够的服务支持(SLA)而已,没有其他功能上的限制,相比它带来的便利,这点小限制还是可以接受的。
顺便再求教一下dotcloud里面的日志怎么弄回本地?SSH上用vim看着太痛苦了,我vim又用得不好,nano也不熟
日志可以打包下载,也可以直接输出到本地,我常用的是这条命令,FYI:
dotcloud run dmyz.www “ls /var/log/nginx/*access.log | xargs cat” > access.log
不错。不过我想问下404是不是需要做些什么设置?或者必须要包含什么内容?
我设置的404文件无论如何都读不出来,总是使用默认的404。我已经把404.html放在static下面了
1.在settings文件中设置DEBUG = False ,这样就不会出现默认的Django 404页面了;
2.把自定义的404页面放到模板目录下,所以如果模板目录不是static的话,放到static下会找不到
现在不是默认的django404啊= =是nginx404…我自定义了一个静态404,放在项目根目录的static下,但是遇到404还是给我默认的nginx404
nginx404说明Django项目本身配置出错了,先检查一下相应的配置吧,这篇博文就是针对ngnix404错误的。Django还没启动,所以看不到Django定制的404错误页面。
不是,项目本身配置好了已经,可以正常进去,其他的都没有什么问题。但是一旦出现了404错误的时候跳不到我设置好的404.html,而是跳到nginx404
悲剧,我找到问题所在了。因为我使用了jinja2的模版系统,而系统在错误的情况下渲染不了jinjia2的标签,所以那两个404和500会出错,于是系统就调用nginx404了……改成默认标签就没问题了。
抱歉是我理解错了。
谢谢分享,jinjia的模板还没在dotcloud的项目里用过,学习了。
我的项目在本地能跑,所以应该不是项目的问题。是在INSTALLED_APPS 那里,我发现如果我不加上我的项目名,就是说不用 ‘wesley.account’而用’account’的话也会报404错误,这是怎么回事?
这个我没写,谢谢补充。
因为在dotcloud上运行时,目录是dmyz-on-dotcloud,而不是dmyz,所以app直接放在项目目录下,在INSTALLED_APPS里直接添加app名也会导致404错误。
可以在setting目录里加上这段代码
就是把当前项目目录加入到path里,这样就解决了。
明白了!谢谢!
你把数据库放app文件夹里,每次更新,数据库就没了……应该放到/home/dotcloud文件夹里才比较好吧……
没太明白…dotcloud push命令上传的文件都会在 */home/dotcloud/版本号* 的文件夹里,如果想把数据库放在*/home/dotcloud* 的话要怎么传上去呢?