Назад | Перейти на главную страницу

Загрузка приложения Python Flask на существующий сервер Apache2 и настройка его прослушивания на другом порту

Быстрый контекст:

У меня есть сервер LAMP Ubuntu 14.04, на котором довольно долгое время размещается мой веб-сайт ExtJS.

Недавно у меня была возможность поработать с DialogFlow, а также я сделал приложение Python Flask, которое будет служить в качестве Webhook, когда DialogFlow достигает выполнения.

Теперь я смог протестировать свое приложение Python. Я запустил его, а затем использовал ngrok, чтобы получить публичный IP-адрес для своего веб-перехватчика. Мой настраиваемый DialogFlow может отправлять POST-запрос в мое приложение Python, а мое приложение Python может анализировать запрос и выдавать желаемый результат.

Теперь я хочу загрузить это приложение Python Flask на свой веб-сервер. У меня проблемы с большинством встреченных мною руководств:

  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 my.email@my.domain.com
            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 my.email@my.domain.com
            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_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 будет принимать запрос POST от DialogFlow, а затем использовать его в качестве входных данных во внутреннем процессе, а затем возвращать результат в DialogFlow для ответа.

Теперь, в моем веб-перехватчике выполнения DialogFlow, я добавил свой URL-адрес и порт как таковые:

https:www.mysite.com:5000

Я пытаюсь выполнить запрос, который, как я знаю, работает, но это не так. Когда я просматриваю диагностическую информацию, она сообщает мне, что истекло время ожидания запроса. Я знаю, что это работает, потому что, когда я подключаю локальную версию к ngrok и подключаю ее к DialogFlow, она работает нормально.

Теперь я не знаю, что делать дальше. Похоже, я не могу добавить порт 5000 в свой port.conf файл, поскольку он заблокирует запуск моего приложения Python Flask на порту 5000. Однако также кажется, что этого недостаточно, чтобы добавить VirtualHost для порта 5000 на моем default-ssl.conf файл.

Есть идеи, как сделать приложение Python Flask видимым для внешнего мира?