快速背景:
我有一个 Ubuntu 14.04 LAMP 服务器,它已经托管我的 ExtJS 网站很长时间了。
最近,我有机会摆弄 DialogFlow,并且我还制作了一个 Python Flask 应用程序作为 DialogFlow 实现时的 Webhook。
现在,我可以测试我的 Python 应用了。我运行它,然后使用 ngrok 为我的 webhook 获取公共 IP。我的自定义 DialogFlow 能够向我的 Python 应用发送 POST 请求,而我的 Python 应用能够解析该请求并提供我想要的输出。
现在,我想将此 Python Flask 应用程序上传到我的 Web 服务器。我见过的大多数指南都存在问题:
- 他们监听端口 80——这会阻止我现有的网站
- 它们不适用于 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 应用程序对外界可见?