1
记录 apache+mod_wsgi+flask 基于 python3 详细安装步骤,同时配置站点访问的 html 和站点 restful api 请求

本机环境介绍

  1. 已安装 apache/2.4.6
  2. 已安装 python3.6
  3. 系统是 centos7

安装 mod_wsgi

因为我是按照 apache 加载扩展的方式引入 mod_wsgi ,所以我需要拿到编译后的 mod_wsgi.so 文件。可以自己去 github下载文件进行编译安装,下面是我使用的 pip3 安装

  1. 使用 pip3 安装 mod_wsgi

    $ yum install python36-devel httpd-devel
    $ /usr/bin/pip3 install -v mod_wsgi
  2. 安装成功后找到 mod_wsgi 文件夹下 server 文件夹 path/to/python3.6/site-package/smod_wsgi/server,在该文件夹下有个 mod_wsgi 的 .so 文件 mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so,在 apache 中引入该扩展:

    # 进入 mod_wsgi 下 server 文件夹
    $ cd /usr/local/lib64/python3.6/site-packages/mod_wsgi/server
    # 将文件夹下 mod_wsgi.so 文件复制到 apache 的 modules 模块下
    $ cp mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so /usr/local/apache/modules/mod_wsgi.so

在虚拟环境中安装Flask

  1. pip 安装virtualenv

    $ pip3 install virtualenv
  2. 创建开发项目 project ,并进入该项目

    $ mkdir project
    $ cd project
  3. 创建一个独立的Python运行环境,命名为 venv ,并用 source 进入该环境

    $ virtualenv --no-site-packages venv
    $ source venv/bin/activate
  4. 在虚拟环境中安装 flask

    $ pip3 install flask

配置站点

/data/www/project 
├── api
│    └── api.py
├── index.html

站点目录结构如图所示,首页是根目录下的 index.html 请求http://localhost/index.html ,api请求为 http://localhost/api/list

  1. 在 api 目录下新建文件 app.wsgi

    import sys
    sys.path.insert(0, "/data/www/project/api/")
    from api import app as application
    
    if __name__ == "__main__":
       application.run()
  2. 编辑 api.py 文件

    from flask import Flask,jsonify
    app = Flask(__name__)
    
    @app.route('/list')
    def getList():
        return jsonify('success')
    
    if __name__ == '__main__':
        app.run()

配置 Apache

  1. 加载 mod_wsgi.so 模块,修改 apache 的 httpd.conf ,加入 LoadModule wsgi_module modules/mod_wsgi.so

    $ vim /usr/local/apache/conf/httpd.conf
    LoadModule wsgi_module modules/mod_wsgi.so
  2. 修改站点配置文件

    $ vim /usr/local/apache/conf/vhost/default.conf
    <VirtualHost *:80>
      ServerName localhost
      
      # 指定根目录
      DocumentRoot /data/www/project/
      
      # WSGIDaemonProcess用于指定应创建不同的守护进程,设置守护进程组的名称为 wsgi_api
      # threads 指定线程数为5
      # python-home 指定守护进程使用的 Python 虚拟环境的位置为/data/www/project/venv
      # python-path 引用 Python 虚拟环境的 site-packages 目录
      WSGIDaemonProcess wsgi_api threads=5 python-home=/data/www/project/venv python-path=/data/www/project/venv/lib/python3.6/site-packages
      
      # WSGIScriptAlias 与 Alias 指令相同,将特定文件路径 /api 标记为脚本 /data/www/project/api/app.wsgi,此脚本应由mod_wsgi 的 wsgi-script 处理程序处理
      WSGIScriptAlias /api /data/www/project/api/app.wsgi
      
      <Directory /data/www/project/api>
           WSGIProcessGroup wsgi_api
           WSGIApplicationGroup %{GLOBAL}
           # WSGIScriptReloading 设置对WSGI脚本文件的更改都触发重新加载机制
           WSGIScriptReloading On
           AllowOverride None
           Require all granted
        </Directory>
    </VirtualHost>
  3. 重启 apache

    $ /etc/init.d/httpd restart

测试

  1. 直接访问首页 http://localhost/index.html
  2. 请求接口 curl http://localhost/api/list

遇到并解决的问题

问题1:

/usr/bin/pip3 install -v mod_wsgi 报错 src/server/wsgi_python.h:24:20: fatal error: Python.h: No such file or directory

答案:
$ yum install python36-devel httpd-devel
问题2:

apache 可以不加配置选项 WSGIDaemonProcess

答案:

修改 app.wsgi 文件为

# 进入虚拟环境
activate_this = '/data/www/project/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

import sys
sys.path.insert(0, "/data/www/project/api/")
from api import app as application

if __name__ == "__main__":
   application.run()

参考资料

  1. mod_wsgi 文档
  2. mod-wsgi 4.7.1 安装文档

Cindy
1.8k 声望390 粉丝