У меня нет большого опыта работы с python, и я впервые загружаю что-то вручную (с файлами .conf). У меня есть приложение, созданное с помощью Flask, и я хочу загрузить его на сервер. Я использовал гуникорн и nginx. Nginx выдал несколько ошибок и обнаружил, что приложение не работает с gunicorn (поэтому я еще не отлаживал nginx). Приложение работает нормально с командой flask run --host=0.0.0.0
и с командой python app.py
. Я считаю, что ошибка связана с тем, как я импортирую свои файлы в python, но я не уверен. Журнал ошибок такой:
[2022-05-16 15:40:39 +0200] [127342] [INFO] Starting gunicorn 20.1.0
[2022-05-16 15:40:39 +0200] [127342] [INFO] Listening at: http://0.0.0.0:8003 (127342)
[2022-05-16 15:40:39 +0200] [127342] [INFO] Using worker: sync
[2022-05-16 15:40:39 +0200] [127343] [INFO] Booting worker with pid: 127343
[2022-05-16 15:41:09 +0200] [127342] [CRITICAL] WORKER TIMEOUT (pid:127343)
[2022-05-16 15:41:09 +0200] [127343] [INFO] Worker exiting (pid: 127343)
[2022-05-16 15:41:10 +0200] [127350] [INFO] Booting worker with pid: 127350
[2022-05-16 15:41:24 +0200] [127350] [ERROR] Exception in worker process
Traceback (most recent call last):
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
worker.init_process()
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 134, in init_process
self.load_wsgi()
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
self.wsgi = self.app.wsgi()
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
return self.load_wsgiapp()
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
return util.import_app(self.app_uri)
File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/util.py", line 359, in import_app
mod = importlib.import_module(module)
File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/var/www/FlaskApp/wsgi.py", line 14, in <module>
from AppName import app
File "/var/www/FlaskApp/AppName/app.py", line 19, in <module>
@app.route('/')
AttributeError: 'NoneType' object has no attribute 'route'
[2022-05-16 15:41:24 +0200] [127350] [INFO] Worker exiting (pid: 127350)
[2022-05-16 15:41:25 +0200] [127342] [INFO] Shutting down: Master
[2022-05-16 15:41:25 +0200] [127342] [INFO] Reason: Worker failed to boot.
Он не может прочитать @app.route('/') из app.py:
-AttributeError: 'NoneType' object has no attribute 'route'
Структура файлов моего проекта:
---AppName
------app.py
------_init_.py (same as app.py)
------main.py (same as app.py)
------file1.py
------file2.py
------folder1
------static
------templates
------folder2
------venv
---wsgi.py
---make-image.sh
---requirements.txt
---gunicorn_starter.sh
---appname.wsgi (I thought maybe the naming needed to be the same with the name of the app)
Я добавил файл сценария оболочки для запуска gunicorn_starter.sh:
#!/bin/sh
gunicorn wsgi:AppName -w 1 --threads 1 -b 0.0.0.0:8003
Примечание: я использовал 2 рабочих 2 потока, затем три, а потом подумал, что для тестирования мне понадобится только один. Не знаю, повлияет ли это на результат.
app.py:
from flask import Flask, request, render_template
from file1 import function
import spacy
from spacy import displacy
nlp = spacy.load("el_core_news_sm")
from flaskext.markdown import Extension,Markdown
def create_app():
#Init App
app = Flask(__name__)
Markdown(app)
app = create_app()
@app.route('/')
def home():
return render_template('index.html')
@app.route('/submit', methods=['POST'])
def submit():
variale1 = function(var)
....some code...
return something
if __name__ == '__main__':
app.run(host='0.0.0.0')
wsgi.py:
import os
import sys
fpath = os.path.join(os.path.dirname(__file__),'AppName')
sys.path.append(fpath)
#print("||the system path||",sys.path)
import file2
import file1
import AppName
from AppName import app
if __name__ == "__main__":
# app = create_app()
app.run()
НГИНКС:
Я запускаю его со службой в /etc/systemd/system/AppName.service .
AppName.service:
[Unit]
Description=Gunicorn instance to serve AppName
After=network.target
[Service]
User=user1
Group=www-data
WorkingDirectory=/var/www/FlaskApp/AppName
Environment="PATH=/var/www/FlaskApp/AppName/venv/bin"
ExecStart=/var/www/FlaskApp/AppName/venv/bin/gunicorn -w 2 --bind unix:AppName.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
Здесь nginx выдает ошибку, что он не может подключиться к сокету, и это было из-за того, что gunicorn не был запущен.
Этот сервис используется с /etc/nginx/sites-available/AppName.conf.
AppName.conf:
server {
listen 80;
server_name domainname.com www.domainname.com;
location / {
include proxy_params;
proxy_pass http://unix:/var/www/FlaskApp/AppName/AppName.sock;
}
}
Затем я использую команды:
sudo systemctl start AppName
sudo systemctl enable AppName
sudo systemctl status AppName
И добавить символическую ссылку в site-enabled. Затем я просто запускаю nginx.
Я видел сообщение, в котором говорится об использовании декораторов функций: https://stackoverflow.com/questions/2757496/using-python-decorator-functions-from-a-different-module
Но я не знаю многого о питоне, поэтому я очень запутался с этим. Я даже не уверен, является ли это ошибкой или тем, как у меня есть файл в этом.py.
Я следовал этим руководствам:
https://www.linkedin.com/pulse/building-deploying-production-ready-flask-app-anand-iyer
https://gunicorn.org/#deployment
https://docs.gunicorn.org/en/stable/deploy.html
https://towardsdatascience.com/understanding-python-imports-init-py-and-pythonpath-once-and-for-all-4c5249ab6355
https://www.geeksforgeeks.org/decorators-in-python/
Основное руководство, которое я использовал, это:
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04
Ссылки, которые я использовал для отладки:
https://stackoverflow.com/questions/66834369/heroku-gunicorn-flask-app-running-error
https://stackoverflow.com/questions/8488482/attributeerror-nonetype-object-has-no-attribute-route-and-webapp2
https://stackoverflow.com/questions/2757496/using-python-decorator-functions-from-a-different-module
Добавьте в оператор возврата функции create_app. В конце функции поместите return app.
Без него он возвращает None, поэтому ожидается, что python не знает, что такое app.route.
Спасибо тебе за это. Я слишком много думал об этом как о веб-приложении и меньше как о питоне. Не могу поверить, что совершил такую ошибку новичка!