Разверните приложение Flask в указанном каталоге: stati c файлы не найдены - PullRequest
2 голосов
/ 22 февраля 2020

Я пытаюсь развернуть Flask веб на сервере Debian. Структура файлов следующая:

run.py
config.py
requirements.txt
/app
    constants.py
    errors.py
    forms.py
    __init__.py
    models.py
    routes.py
    /static
        /css
            /vendor
                bulma.css
        /js
            /vendor
                fontawesome.js

    /templates
        index.html
        login.html
        404.html

Чтобы развернуть ее на сервере, я создаю virtualenv и устанавливаю файл require.txt. Затем я запускаю Интернет с файлом Python run.py. Когда я пытаюсь загрузить страницу индекса или страницу входа, он не может найти какой-либо путь маршрутизации (хотя он работает локально). Кроме того, он не может найти файлы CSS и JS. Вместо этого он запускает обработчик ошибок на errors.py, вызывая ошибку HTML 404. Содержание файлов, в которых, я думаю, может быть обнаружена проблема, приведено ниже:

Содержимое run.py

from app import app, db, socketio
from flask_assets import Environment, Bundle
from flask import Flask

if __name__ == '__main__':
    assets = Environment(app)
    assets.register('mainCss', \
        'css/vendor/bulma.css', filters='cssmin')
    assets.register('mainJs', \
        'js/own.js', 'js/vendor/fontawesome.js', filters='jsmin')

    socketio.run(app, debug=False, port=80, host= '0.0.0.0')

Содержимое config.py

import os
basedir = os.path.abspath(os.path.dirname(__file__))


class Config(object):
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    MAIL_SERVER = os.environ.get('MAIL_SERVER')
    MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
    MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
    MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    ADMINS = ['your-email@example.com']

Содержимое /app/__init__.py

import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from config import Config
from flask_socketio import SocketIO
from threading import Lock

app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)

thread = None
thread_lock = Lock()
socketio = SocketIO(app)

from app import routes, models, errors

Содержимое /app/routes.py

from flask import render_template, flash, redirect, url_for, request
from app import app, db
from app.forms import LoginForm

@app.route('/login', methods=['GET', 'POST'])
def login():

    form = LoginForm()
    if form.validate_on_submit():
        #Validate login
        return redirect(url_for('index'))
    return render_template('login.html', title='Login', form=form)

@app.route('/index', methods=['GET', 'POST'])
def index():
    return render_template('index.html', title='Index')

Поэтому У меня вопрос : почему это работает локально, но не может найти пути файлы stati c при развертывании на сервере Debian и как я могу решить эту проблему?

EDIT : я только что понял, что проблема в том, что на сервере моя страница размещается в дополнительном каталоге, таком как www.myweb.com/directory, в то время как при локальном запуске моя веб-страница находится на localhost:5000/, поэтому страница не может найти файлы CSS и JS на сервере из-за дополнительных directory. Теперь я пытаюсь понять, как соединиться с этим дополнительным уровнем в URL. Я считаю, что это можно сделать с помощью чего-то вроде this , но в настоящее время я не могу найти правильную реализацию для этой проблемы.

1 Ответ

1 голос
/ 28 февраля 2020

Вы можете использовать DispatcherMiddleware

Первым параметром конструктора DispatcherMiddleware является резервное приложение, если пути не найдены, если мы передадим исходный wsgi_app, ваше приложение будет по-прежнему доступно в root path /.

Второй параметр - это словарь префиксов: application. {'/directory': app} сделает запросы /directory перенаправленными в ваше приложение

Вот как вы можете склеить все вместе

from app import app, db, socketio
from flask_assets import Environment, Bundle
from flask import Flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware

if __name__ == '__main__':
    assets = Environment(app)
    assets.register('mainCss', \
        'css/vendor/bulma.css', filters='cssmin')
    assets.register('mainJs', \
        'js/own.js', 'js/vendor/fontawesome.js', filters='jsmin')

    app.wsgi_app = DispatcherMiddleware( 
           app.wsgi_app, # If path is not found use the original wsgi_app
           {'/directory': app} # If prefix is /directory pass it to app
    )
    socketio.run(app, debug=False, port=80, host= '0.0.0.0')
...