将 Python Flask 应用程序上传到现有的 Apache2 服务器并使其监听不同的端口

将 Python Flask 应用程序上传到现有的 Apache2 服务器并使其监听不同的端口

快速背景:

我有一个 Ubuntu 14.04 LAMP 服务器,它已经托管我的 ExtJS 网站很长时间了。

最近,我有机会摆弄 DialogFlow,并且我还制作了一个 Python Flask 应用程序作为 DialogFlow 实现时的 Webhook。

现在,我可以测试我的 Python 应用了。我运行它,然后使用 ngrok 为我的 webhook 获取公共 IP。我的自定义 DialogFlow 能够向我的 Python 应用发送 POST 请求,而我的 Python 应用能够解析该请求并提供我想要的输出。

现在,我想将此 Python Flask 应用程序上传到我的 Web 服务器。我见过的大多数指南都存在问题:

  1. 他们监听端口 80——这会阻止我现有的网站
  2. 它们不适用于 SSL —— 它们大多数使用默认的 http-conf 文件。

由于我的 DialogFlow 与 Google Assistant 集成,因此我的 Python Flask 应用应托管在 HTTPS 服务器上。我使用 Lets Encrypt 获取 SSL。

在继续之前,我想概述一下我的服务器文件结构:

|----->/var/www/html/
    |----->index.html
    |----->FlaskAppFolder
        |----->flask_test.py (my flask app)
        |----->flaskapp.wsgi

这是我的default-ssl.conf文件:

<IfModule mod_ssl.c>
        <VirtualHost _default_:443>
            ServerAdmin [email protected]
            ServerName mysite.com
            ServerAlias www.mysite.com

            DocumentRoot /var/www/html
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            SSLEngine on
            SSLCertificateFile      /etc/apache2/ssl/apache.crt
            SSLCertificateKeyFile /etc/apache2/ssl/apache.key
            <FilesMatch "\.(cgi|shtml|phtml|php)$">
                            SSLOptions +StdEnvVars
            </FilesMatch>

            <Directory /usr/lib/cgi-bin>
                    SSLOptions +StdEnvVars
            </Directory>

            BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
            BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
        </VirtualHost>

        <VirtualHost _default_:5000>
            ServerAdmin [email protected]
            ServerName mysite.com
            ServerAlias www.mysite.com

            WSGIScriptAlias / /var/www/html/FlaskAppFolder/flaskapp.wsgi

            DocumentRoot /var/www/html/DocumentSearcher
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            SSLEngine on
            SSLCertificateFile      /etc/apache2/ssl/apache.crt
            SSLCertificateKeyFile /etc/apache2/ssl/apache.key
            <FilesMatch "\.(cgi|shtml|phtml|php)$">
                            SSLOptions +StdEnvVars
            </FilesMatch>

            <Directory /usr/lib/cgi-bin>
                    SSLOptions +StdEnvVars
            </Directory>

            BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
            BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
        </VirtualHost>

</IfModule>

第一个VirtualHost是默认端口 80,这样我的网站仍会显示出来。第二个VirtualHost是端口 5000,这是我运行 flask 应用时使用的端口。

以下是我的port.conf文件:

Listen 80

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

我发现我无法添加Listen 5000它。我尝试Listen 5000在文件中的任何位置添加,可能是在Listen 50或下Listen 443,我的 Python Flask 应用程序告诉我该端口已被使用。

然后这是我的 flask 应用程序名称 flask_test.py:

import subprocess
import sys
import time

from flask import Flask
from flask import render_template
from flask import make_response
from flask import jsonify
from flask import request

import ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('/path/to/my/apache.crt', '/path/to/my/apache.key')


# app = Flask(__name__)
app = Flask('flaskshell')

# function for responses
def results():
    # build a request object
    req = request.get_json(force=True)

    # fetch action from json
    action = req.get('queryResult').get('action')
    parameters = req.get('queryResult').get('parameters')
    keyword = parameters.get('any');

    result = #some process here
    output = #some process here

    output = output.replace('\n', '\n \n')
    return {'fulfillmentText': 'Result: \n\n' + str(output)}

# create a route for webhook
@app.route('/', methods=['GET', 'POST'])
def webhook():
    # return response
    return make_response(jsonify(results()))

# run the app
if __name__ == '__main__':
   app.run(host='0.0.0.0', ssl_context=context)

最后,我的flaskapp.wsgi文件:

import sys
import logging

logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/var/www/html/DocumentSearcher/")

from flask_test  import app as application

基本上,我确保它在https而不是上运行http,并且使用端口 5000。我的 Python Flask 应用程序将从 DialogFlow 接收 POST 请求,然后将其用作内部进程的输入,然后将结果返回给 DialogFlow 以获得响应。

现在,在我的 DialogFlow 的 Fulfilment Webhook 中,我添加了我的 URL 和端口,如下所示:

https:www.mysite.com:5000

我尝试了一个我知道有效的查询,但它没有用。当我检查诊断信息时,它告诉我请求超时了。我知道它有效,因为当我将本地版本连接到 ngrok,并将其连接到 DialogFlow 时,它工作得很好。

现在我不知道下一步该怎么做。似乎我无法将端口 5000 添加到我的port.conf文件中,因为它会阻止我的 Python Flask App 在端口 5000 上运行。但是,似乎仅在我的文件上为端口 5000 添加 VirtualHost 还不够default-ssl.conf

有什么想法可以使我的 Python Flask 应用程序对外界可见?

相关内容