原文地址:http://blog.leanote.com/post/withoutlee/Ubuntu14.04-Python3.4-apache2.4-Django1.7站点发布笔记
最近在学习python web开发,选择了Django框架,经过一个星期的学习,最终做出了一个简单的博客站点,在Django自带的web server上运行无误,接下来就要将站点发布到生产环境,即Apache等可以用于真正线上环境的web server上。
因为最初学习python和Django框架都是在windows下进行的,因此最先考虑的是在Windows下发布到Apache上,但是在给Apache加载mod_wsgi模块时,总是加载错误,无法启动服务器。查阅众多资料,基本上可以肯定是由于版本不兼容造成的。在学习Django时采用的最新稳定版1.7,Python采用的是Python3版本,而mod_wsgi在window下是没有官方编译版本,而非官方编译的又无法加载,自己编译的总是失败。考虑到真正的服务器以Linux居多,因此,最终决定在Linux下完成发布。
首先是各个组件版本的选择,由于站点的开发使用的是Python3和Django1.7, 考虑代码的最小修改,使用的各个组件版本如下:
这一部分属于操作系统的安装,就不详细叙述了,按照常规的安装方法,安装好操作系统即可。
在Ubuntu14.04版本中,自带了python2.76和python3.40,在终端中输入python则使用2.76版本,输入python3则使用3.40版本。如果使用的操作系统中没有python3,则可以自己安装,但在安装完毕之后,切记不可删除系统自带的python2.x,因为系统的好多组件都依赖于系统自带且默认的python版本。我们只需在使用的时候指明是python还是python3即可。
安装pip
为了后续的使用方便,在安装完python环境并检查无误后,安装python的包管理模块pip。在Ubuntu中,pip针对python2.x和python3.x版本有两个版本,这里我们使用的是python3.4,因此需要安装对应的支持python3.x的版本。
sudo apt-get install pip # 安装python2.x对应的pip
sudo apt-get install pip3 # 安装python3.x对应的pip
安装MySQL connector for python
在站点的开发阶段,没有使用Django自带的SQLite3,而是使用了MySQL。Python有很多连接MySQL的模块,其中Django默认使用的连接MySQL的模块不支持Python3,不过还好,MySQL官方提供的Python连接模块时支持Django的,因此这里我选择安装MySQL connector for python。
在开发阶段,Windows平台下安装该模块特别简单,在MySQL官网选择对应的版本下载即可,但是在Ubuntu下,安装时遇到了问题。
在MySQL官网,看到Linux下提供的有Ubuntu平台的预编译版本,就选择了下载这个,但是在安装过程中提示各种包依赖问题,要解决一个就需要解决更多的包依赖问题,这里可能跟Python的版本有关。通过上网查询资料,有一篇博客中建议在下载时选择平台无关版本,下载完成后,进入下载目录,执行如下操作:
tar zxvf mysql-connector-python-2.0.2
cd mysql-connector-python-2.0.2/
python3 setup.py install
通过上述操作,即可完成MySQL connector for Python的安装,这里特别注意的是第三条命令,一定要使用Python3来安装,如果使用Python来安装,则该模块会被安装到Python2.x版本中,导致后续的Django不能正常连接数据库。
安装完成后,可以在Python shell中导入该模块,连接数据库,以测试模块是否安装正确。
在使用Django框架做开发的过程中,还需要做具体的配置,具体信息参见Django开发环境配置文章。
在上述的工作都完成以后,安装Django就非常简单了,为了以后的管理方便,不被各种的版本问题干扰,这里推荐使用python的虚拟环境virtualenv。但是在本文中,并没有使用该模块,而是直接安装进Python环境(这里非常不推荐此种方法)。
使用pip模块安装Django:
pip3 install django==1.7
通过上述命令,就可以完成django的安装,在Python3的shell中,运行如下命令来检查Django是否安装成功:
>>> import django
>>> print(django.get_version())
1.7
安装Apache
Apache的安装就比较简单了,在Linux各个发行版中,都有自己的软件包管理器,使用这些管理器安装软件比较简单,它们会自动解决各种包依赖问题。在Ubuntu下,使用如下命令来安装Apache:
sudo apt-get install apache2
接下来可以通过本地访问127.0.0.1或者查看进程来确定Apache是否安装成功。以下是Apache的几个常用命令:
service apache start
service apache stop
service apache restart
service apache reload
安装mod_wsgi模块
使用如下命令安装该模块:
sudo apt-get install libapache2-mod-wsgi-py3
这里需要特别指出安装的针对Python3版本的mod_wsgi模块,如果要安装针对Python2.x的版本,则需要使用如下命令:
sudo apt-get install libapache2-mod-wsgi
如果同时安装了两个版本的模块,则Apache会优先使用针对python2.x的版本。
目前为止,所有的软件都已安装完毕,并且保证可用,下面就进行具体的配置。
在Ubuntu14.04中安装的Apache2.4,配置文件的存在方式发生了变化,为了使配置文件阅读和存储更加方便有条理,Apache将配置信息由原来一个文件httpd.conf分割成了多个,存放在各个目录中,方便了管理和扩展。下面是Apache配置文件中的一个存放配置文件的目录示意图:
# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf
其中apache2.conf是主配置文件,具体的说明文件可以参考该文件。
接下来为写好的站点配置一个虚拟主机:
cd /etc/apache2/sites-available
vim firstsite.conf
在该文件中加入如下内容:
<VirtualHost *:80>
ServerName www.firstsite.com
DocumentRoot /home/lee/Documents/pythonweb/firstsite
<Directory /home/lee/Documents/pythonweb/firstsite/firstsite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/lee/Documents/pythonweb/firstsite/firstsite/wsgi.py
Alias /firstsite/static/ /var/www/firstsite/static/
</VirtualHost>
WSGIPythonPath /home/lee/Documents/pythonweb/firstsite
其中:
上面的配置就可以完成Django站点的基本配置,因为wsgi文件在Django1.7中是默认创建的,里边有一些基本信息,可以保证站点的运行,额外的信息需要自己额外配置。
接下来,使用如下Apache命令,将该配置文件启用:
a2ensite firstsite.conf # enable该站点
service apache reload # 重新加载Apache服务器配置
如果提示成功,则表示配置成功,这时根据上述配置文件中的server name,修改hosts文件,在浏览器中访问该站点,具体地址根据server name和Django项目的设置来确定。
至此,就可以在浏览器中访问站点了,如果上述配置都正常的情况下,就可以看到网站的界面了,但这时候最可能出现的问题是网站的样式都没有加载,这时候并不是Apache配置的错误,而是Django关于静态文件的发布需要额外配置。
在上面的过程中,最后访问站点会发现网站样式表、图片和js文件的缺失,这种情况的原因就是上边提到的Django不负责静态文件(css/js/image)的处理,而是留给具体的服务器来做静态文件的处理。在开发阶段,当DEBUG=FALSE时,Django自带的简单web server和内部机制( django.contrib.staticfiles)可以负责静态文件处理,这种方法效率低下且存在安全隐患,所以不能用于生产环境,因此在生产环境中或者DEBUG=FALSE的时候,Django是不处理静态文件的,必须配置由真实环境中的web server来处理,下面就介绍Django框架中静态文件的发布和配置。
下面先介绍几个关于static files的设置选型:
理解了上边三个设置选项,就可以很轻松的发布静态资源文件了,比如在我的项目中,前两个选项设置如下:
STATIC_URL = '/firstsite/static/'
STATIC_ROOT = '/var/www/firstsite/static/'
完成上述选项配置,且在Apache配置文件中也写好Alias以后,再访问页面就可以看到正确的样式了。
但是,在访问Django自带的admin页面时,依然是样式缺失,这时候就用到STATICFILES_DIRS设置了,这里很明显,admin所用到的静态文件是存放在Django的安装位置的,即存在另一个工程里面,与STATICFILES_DIRS的描述很相似。因此,找到admin资源文件的目录,做如下设置:
STATICFILES_DIRS = (
'/usr/local/lib/python3.4/dist-packages/django/contrib/admin/static/',
)
完成上述设置后,重新加载服务器,则可以正常访问到admin的静态资源了。至此,整个Django项目的发布就完成了,当然还有一些Django项目相关的配置,如关闭Debug等操作,就不在详细叙述。
在一切都设置好后,访问页面,发现Django返回的错误信息是找不到模版,仔细阅读了Django的模版加载机制和顺序,仔细核实了错误信息中显示的Django寻找模版的地方,发现我的模版是存在的,路径也是对的。后来,查阅网上的信息,根据Stack上的一个提示,检查了文件的权限问题,发现问题果然在这里。
因为我的模版文件是在Windows下写好直接拷贝过来的,它的权限都被设置为700,Django是不能访问的,所以会提示模版找不到。
解决办法:将相关的目录权限设置为755,即具有读和执行权限,重新刷新页面,发现可以访问了。