【问题标题】:How to deploy Python Flask app to Apache (Httpd) running on Amazon Linux EC2 instance如何将 Python Flask 应用程序部署到在 Amazon Linux EC2 实例上运行的 Apache (Httpd)
【发布时间】:2016-05-24 22:48:26
【问题描述】:

我在这里真的很挣扎。我有一个我开发的简单 Python Flask REST API。该 API 在我的本地开发环境 (Mac OS X) 中运行良好,并且在通过我的 EC2 实例上的控制台直接执行时运行良好。

我想将此服务投入生产,因此想将它托管在运行在 EC2 实例上的 Apache 后面。这是我一直碰壁的地方,我似乎无法克服配置和错误。我在网上研究了几篇文章和这里的问题,似乎没有一个能够帮助我。

我希望这里有人可以为我提供有关如何将我的服务部署到在 Amazon Linux EC2 实例上运行的 Apache 后面的生产的分步指导。

以下是我采取的步骤:

  1. 启动了一个基本的 Amazon Linux EC2 实例。
  2. 对实例应用更新,sudo yum update
  3. 安装 Apache 和 WSIG,sudo yum install httpd24 mod24_wsgi
  4. 启动 Apache,sudo service httpd start
  5. 配置 Apache 自动启动,sudo chkconfig httpd on
  6. 通过点击我的 EC2 机器的 DNS 进行测试。我成功获得了 Amazon Linux AMI 测试页面。
  7. 如下调整 /var/www 的权限
    • sudo groupadd www
    • sudo usermod -a -G www ec2-user
    • 登录/注销并确认会员资格,群组
    • sudo chown -R root:www /var/www
    • sudo chmod 2775 /var/www
    • 找到 /var/www -type d -exec sudo chmod 2775 {} \;
    • 找到 /var/www -type f -exec sudo chmod 0664 {} \;
  8. 通过访问我的 EC2 机器的 DNS 进行测试 - 到目前为止仍然很好。

现在我知道我的实例正在运行,我想创建两个文件夹,我可以在其中测试和运行我的 Python Flask 代码。我这样做如下:

  1. 我创建了两个文件夹,一个用于开发,一个用于生产。
    • /var/www/rest-dev/
    • /var/www/rest-prod/
  2. 我在每个文件夹中设置了一个虚拟环境并安装了 Flask。
    • 虚拟环境
    • env/bin/pip install Flask
    • 然后我将我的服务的副本放在每个文件夹中。
    • 然后我在 app.py 上设置权限,chmod a+x app.py
    • 我可以成功执行 ./app.py 并通过点击 DNS 名称 + 端口 5000 来测试服务。它可以工作。

现在这就是我被绊倒的地方。我的目标是能够访问 api.example.com 并加载我的服务的根目录。在下面的示例代码中,“Hello, World!”应该只是显示。

我按照这里找到的教程没有运气。

http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/

http://webpy.org/cookbook/mod_wsgi-apache

http://www.jakowicz.com/flask-apache-wsgi/

执行上述任何文章中的任何步骤后,我都会收到一个 HTTP 错误页面,并且不再加载任何内容,包括默认的 Amazon Linux AMI 测试页面。以下是我更改的代码和配置。我没有更改我的 httpd.conf ...应该吗?我可能还缺少其他几件事。

有人可以帮我详细介绍纠正错误的必要步骤吗?

非常感谢!

当我查看 HTTPD 的 error_log 时,它会列出如下错误:

mod_wsgi (pid=8270): Target WSGI script '/var/www/rest-dev/deploy.wsgi' cannot be loaded as Python module.
mod_wsgi (pid=8270): Exception occurred processing WSGI script '/var/www/rest-dev/deploy.wsgi'.
Traceback (most recent call last):
  File "/var/www/rest-dev/deploy.wsgi", line 16, in <module>
    from app import app as application
  File "/var/www/rest-dev/app.py", line 2, in <module>
    from flask import Flask
ImportError: No module named flask

这是我的 deploy.wsgi 文件,位于 rest-dev 文件夹中:

import os
import sys
import site

# Add virtualenv site packages
site.addsitedir(os.path.join(os.path.dirname(__file__),     'env/local/lib64/python2.7/site-packages'))

# Path of execution
sys.path.append('/var/www/rest-dev')

# Fired up virtualenv before include application
activate_env = os.path.expanduser(os.path.join(os.path.dirname(__file__), 'env/bin/activate_this.py'))
execfile(activate_env, dict(__file__=activate_env))

# import my_flask_app as application
from app import app as application

这是我位于 /etc/httpd/conf.d/ 中的 vhost.conf 文件

<VirtualHost *:80>
        ServerName api.example.com

        WSGIDaemonProcess webtool user=ec2-user group=www threads=5 home=/var/www/rest-dev/
        WSGIScriptAlias / /var/www/rest-dev/deploy.wsgi

        <directory /var/www/rest-dev>
                WSGIProcessGroup webtool
                WSGIApplicationGroup %{GLOBAL}
                WSGIScriptReloading On
                Order deny,allow
                Allow from all
        </directory>
</VirtualHost>

这是我的app.py示例服务代码供参考:

#!env/bin/python
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, World!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

【问题讨论】:

  • usergroup 指令中的 WSGIDaemonProcess 设置仅在 apache 以 root 身份启动时应用,它可能不在这里。这意味着所有文件和目录(包括 virtualenv 目录!)都需要 apache 用户访问。你确定是吗?
  • 我不知道。如有必要,我该如何判断和更改?
  • 你可以su给apache用户看看你是否可以访问它(sudo su apache -s /bin/bash)。如果没有,您可以将目录设为全球可读 (chmod a+rX venvdir) 或由 apache-group 和 group 可读 (chmod g+rX -R venvdir) 拥有...
  • 我执行了sudo su apache -s /bin/bash,我相信它有效。提示改为[apache@ip-123-45-67-89 httpd]$
  • 所以现在尝试 cd 到 virtualenv 看看你是否可以访问这些文件...

标签: python apache amazon-ec2 flask mod-wsgi


【解决方案1】:

事实证明,在我的 deploy.wsgi 文件中,我引用的是 lib64 而不仅仅是 lib。所有站点包都存在于 lib 中。

更改它并重新启动 Apache 后,我能够成功地从 URL 访问我的服务。

【讨论】:

  • @arun 从 web 访问时,你使用的是 5000 端口还是 80 端口?
  • 它可以是您通过 Flask app.run 定义的任何端口,但通常会避免使用端口 80 进行测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多