mac系统版本为OS X EI Capitan 10.11.4
(其实系统已经安装好了管理员权限的apache,在/etc/apache2下,但是我们还是要安装用户权限的apache,方便更改文件不需要权限)
默认已经在mac上面安装好了用户权限的apache。(如果没有安装好的话,传送门:Apache Installing
apache安装的一些小问题
我简单说说在安装apache过程中遇到的问题:
- 如果遇到OSError或者写入错误的话,一般是没有root目录下的写入权限,使用sudo命令获得权限就好。
- configure: error: C compiler cannot create executables 解决方法传送门
- 通常在安装的过程中会遇到各种各样的工具缺失,比如apr,pcre等,去官网下载源码下来解压,然后运行configure文件后编译就好了。命令如下:
./configure --prefix=安装地址
make
make install
#如果想清除之前的.o文件可以使用make distclean
安装好apache之后命令行进入bin目录下运行./apachectl start启动apache服务。
- 启动过程中最常见的就是80端口被占用,体现为套接字无法绑定地址,为了省事,我直接将apache中conf目录下的httpd.conf文件中监听的端口改成了8000。
Listen 127.0.0.1:8000
- 以及还遇到了这个错误:httpd: Could not reliably determine the server’s fully qualified domain name, using 127.0.0.1 for ServerName
这里需要改一下/etc/hosts文件以及ServerName属性,详细解决方法看以上链接。
开启浏览器输入localhost后返回it works之后apache则安装成功。
apache安装扩展模块mod_wsgi
安装方法传送门:mod_wsgi installation
第一种方法是传统的apache安装扩展模块的方法,先下载mod_wsgi源码,configure然后再编译安装,然而因为在make intall的时候出现了root权限问题(用sudo也无法解决,详细的情况讨论请参见这里),所以我选择了用第二种方法安装mod_wsgi模块。
第二种方法就是直接用pip安装mod_wsgi,安装好之后将mod_wsgi-py27.so的路径配置在httpd.conf文件中。命令如下:
[sudo] pip install mod_wsgi
mod_wsgi-express module-location
#将输出的路径复制到httpd.conf中,假设输出的路径为/user/local/mod_wsgi-py27.so
#在http.conf中写入以下命令:
LoadModule wsgi_module /user/local/mod_wsgi-py27.so
重新启动apache服务器,mod_wsgi模块就应该安装好了。
hello world example 与 mod_wsgi模块交互
接下来可以试一下用一个简单的hello world application来测试一下mod_wsgi模块的正常工作。
定义一个符合WSGI标准的application并保存该文件为hello.wsgi。(如果不太清楚WSGI标准的可以参看我的一篇博客:WSGI初探及wsgiref简单实现)
#hello.wsgi
def application(environ, start_response):
status = "200 OK"
response_headers = [(‘Content-type‘, ‘text/plain‘)]
output = "hello world!"
start_response(status, response_headers)
return [output]
我尝试用了两种方法来配置apache使其调用hello.wsgi返回hello world。
- 第一种方法就是直接将hello.wsgi放在apache的根目录下访问,比较简单。
- 第二种方法就是在apache上配置一个虚拟主机,通过自己设置的域名来访问hello.wsgi。
我们先来看第一种方法:
- 首先打开conf目录下的httpd.conf文件(就是apache的主服务器的配置文件),找到DocumentRoot变量,它的值就是apache服务器的根目录,把你的hello.wsgi文件拖到该目录下。(注意,在mac下应该已经确认在Finder中打开所有的文件后缀名,hello.wsgi的后缀名为.wsgi,当然,不一定要使用后缀名.wsgi,也可以使用.py后缀)
- 然后在DocumentRoot变量(假设为/Users/Apache/WWW)下设定WSGI脚本的别名:
WSGIScriptAlias /hello.wsgi /Users/Apache/WWW/hello.wsgi
在打开apache服务后,我们在浏览器中输入localhost :8000/hello.wsgi (监听的端口为8000),即可看到“hello world!”。
值得注意的是,如果WSGIScriptAlias设置成了:
WSGIScriptAlias / /Users/Apache/WWW/hello.wsgi
那么在WWW目录下的所有静态文件都会被屏蔽,对localhost:8000/*(*表示任意字符)的任意访问都会转换成对hello.wsgi的访问。如果我们还想要访问在WWW目录下的静态文件,则需要用到Alias指令。
第二种方法:
1.首先 在http.conf文件中设置可以引入包含虚拟主机的文件:
# Virtual hosts
# Include conf/extra/httpd-vhosts.conf
将上面的#去掉就可以引入虚拟主机的配置文件了
2.在extra目录下找到http-ghosts.conf配置virtual host,基本跟配置主服务器一样:
(假设虚拟主机的根目录为/Users/Apache/VirtualHost,监听的端口为8001)
<VirtualHost *:8001>
DocumentRoot "/Users/Apache/VirtualHost"
ServerName www.virtualhost.com
ServerAlias virtualhost.com
WSGIScriptAlias /hello.wsgi /Users/Apache/VirtualHost/hello.wsgi
DirectoryIndex index.html
<Directory "/Users/Apache/VirtualHost">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
3.在设置完虚拟主机的配置文件之后,我们还不能在浏览器中立即测试我们的新域名,我们还要将新域名和127.0.0.1绑定起来。因此打开/etc/hosts文件,绑定域名和地址(修改文件需要权限):
127.0.0.1 virtualhost.com
那么/etc/hosts为什么要这样设定呢?
一般来说,当浏览器得到域名的时候,浏览器首先通过/etc/hosts文件查询它的ip地址,得不到ip的时候再向DNS服务器查询。因此,如果我们在mac上设置了shadowsocks的全局代理,所有的请求直接走代理,那么我们就获取不到这个我们自己创立的域名的ip地址了。(所以记得关闭你的翻墙工具)
此时,我们打开浏览器就可以输入virtualhost.com:8000/hello.wsgi就能看到“hello world!”了。
关于mod_wsgi模块的embedded mode(嵌入模式)与Daemon Process(守护进程)
mod_wsgi模块在加载WSGI应用程序的时候有两种不同的模式,默认使用的是嵌入模式,而另一种模式是守护进程,等会我们会讲述如何开启守护进程。
这两种模式有什么不同呢?嵌入模式将会直接在apache的子进程中加载WSGI Application,而守护进程则会在与apache进程的不同进程中加载,需要进行进程间的通信机制。因此,如果对WSGI Application的代码进行了修改,那么在嵌入模式下需要重启apache服务器,而在守护进程下则不需要重启服务器。
以及,如果多个django的项目布置在同一台apache服务器上,也是推荐用守护进程,否则进程中的settings module会相互错乱,具体参考这里:How to use Django with Apache and mod_wsgi
接下来是Daemon process的virtualhost配置代码:
这里写代码片