gpt4 book ai didi

apache - 使用 mod_wsgi 在 Apache 上部署 Flask

转载 作者:行者123 更新时间:2023-12-01 19:40:11 25 4
gpt4 key购买 nike

我正在尝试部署一个我构建的 Flask Web 应用程序,以部署在 Apache 服务器上。我在 Raspberry Pi 3 上使用 Raspbian (Jessie) 操作系统。该应用程序在 Flask 内置开发 Web 服务器上运行完美,但我无法将其部署在 Apache 服务器上。

这就是我所做的:

sudo apt-get update
sudo apt-get -y install python3 ipython3 python3-flask
sudo apt-get -y install apache2
sudo apt-get -y install libapache2-mod-wsgi-py3

conf 文件为:/etc/apach2/sites-available/arduinoweb.conf:

<VirtualHost *>
ServerName 10.0.0.20

WSGIDaemonProcess arduinoweb user=pi group=pi threads=5
WSGIScriptAlias / /var/www/ArduinoWeb/arduinoweb.wsgi

<Directory /var/www/ArduinoWeb/ArduinoWeb>
WSGIProcessGroup arduinoweb
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Require all granted
</Directory>

Alias /static /var/www/ArduinoWeb/ArduinoWeb/static
<Directory /var/www/ArduinoWeb/ArduinoWeb/static/>
Require all granted
</Directory>

Alias /temp /var/www/ArduinoWeb/ArduinoWeb/temp
<Directory /var/www/ArduinoWeb/ArduinoWeb/temp/>
Require all granted
</Directory>

Alias /templates /var/www/ArduinoWeb/ArduinoWeb/templates
<Directory /var/www/ArduinoWeb/ArduinoWeb/templates/>
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined


</VirtualHost>
~

/var/www/Arduinoweb/arduinoweb.wsgi中的WSGI脚本文件:

import sys

if sys.version_info[0]<3: # require python3
raise Exception("Python3 required! Current (wrong) version: '%s'" % sys.version_info)

sys.path.insert(0, '/var/www/Arduinoweb/Arduinoweb')

from app import app as application

Apache的错误日志:

[Wed Sep 21 21:46:22.669633 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] mod_wsgi (pid=17681): Target WSGI script '/var/www/ArduinoWeb/arduinoweb.wsgi' cannot be loaded as Python module.
[Wed Sep 21 21:46:22.669971 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] mod_wsgi (pid=17681): Exception occurred processing WSGI script '/var/www/ArduinoWeb/arduinoweb.wsgi'.
[Wed Sep 21 21:46:22.670196 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] Traceback (most recent call last):
[Wed Sep 21 21:46:22.671185 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] File "/var/www/ArduinoWeb/arduinoweb.wsgi", line 8, in <module>
[Wed Sep 21 21:46:22.671238 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] from app import app as application
[Wed Sep 21 21:46:22.671406 2016] [wsgi:error] [pid 17681:tid 1972667440] [client 10.0.0.3:64819] ImportError: No module named 'app'

我不明白为什么它找不到该应用程序。

这是Python文件/var/www/Arduinoweb/Arduinoweb/app.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask import request, redirect, url_for, render_template, jsonify
from socket import *
from time import time
from threading import Timer
from datetime import datetime
import fileinput

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:Qazwsx@localhost/arduinoweb'
app.debug = True
db = SQLAlchemy(app)

class User(db.Model):

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)

def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<user %r>' % self.username


class Temp(db.Model):
__tablename__ = "Temp"
id = db.Column("id", db.Integer, primary_key=True)
Temp = db.Column("Temp", db.Integer)
Date = db.Column("Date", db.Date)
Time = db.Column("Time", db.Time)
DateTime = db.Column("DateTime", db.String)

def __init__(self, Temp, Date=None, Time=None, DateTime=None):
self.Temp = Temp
if Date is None:
Date = str(datetime.now()).split('.')[0]
self.Date = Date
if Time is None:
Time = str(datetime.now()).split('.')[0]
self.Time = Time
if DateTime is None:
DateTime = repr(datetime.now().replace(second=0, microsecond=0)).split('datetime.datetime',1)[1]
self.DateTime = DateTime

class EC(db.Model):
__tablename__ = "EC"
id = db.Column("id", db.Integer, primary_key=True)
EC = db.Column("EC", db.Float)
Date = db.Column("Date", db.Date)
Time = db.Column("Time", db.Time)
DateTime = db.Column("DateTime", db.String)

def __init__(self, EC, Date=None, Time=None, DateTime=None):
self.EC = EC
if Date is None:
Date = str(datetime.now()).split('.')[0]
self.Date = Date
if Time is None:
Time = str(datetime.now()).split('.')[0]
self.Time = Time
if DateTime is None:
DateTime = repr(datetime.now().replace(second=0, microsecond=0)).split('datetime.datetime',1)[1]
self.DateTime = DateTime

class PH(db.Model):
__tablename__ = "PH"
id = db.Column("id", db.Integer, primary_key=True)
PH = db.Column("PH", db.Float)
Date = db.Column("Date", db.Date)
Time = db.Column("Time", db.Time)
DateTime = db.Column("DateTime", db.String)

def __init__(self, PH, Date=None, Time=None, DateTime=None):
self.PH = PH
if Date is None:
Date = str(datetime.now()).split('.')[0]
self.Date = Date
if Time is None:
Time = str(datetime.now()).split('.')[0]
self.Time = Time
if DateTime is None:
DateTime = repr(datetime.now().replace(second=0, microsecond=0)).split('datetime.datetime',1)[1]
self.DateTime = DateTime

class Humidity(db.Model):
__tablename__ = "Humidity"
id = db.Column("id", db.Integer, primary_key=True)
Humidity = db.Column("Humidity", db.Integer)
Date = db.Column("Date", db.Date)
Time = db.Column("Time", db.Time)
DateTime = db.Column("DateTime", db.String)

def __init__(self, Humidity, Date=None, Time=None, DateTime=None):
self.Humidity = Humidity
if Date is None:
Date = str(datetime.now()).split('.')[0]
self.Date = Date
if Time is None:
Time = str(datetime.now()).split('.')[0]
self.Time = Time
if DateTime is None:
DateTime = repr(datetime.now().replace(second=0, microsecond=0)).split('datetime.datetime',1)[1]
self.DateTime = DateTime

class HumidityRoots(db.Model):
__tablename__ = "HumidityRoots"
id = db.Column("id", db.Integer, primary_key=True)
HumidityRoots = db.Column("HumidityRoots", db.Integer)
Date = db.Column("Date", db.Date)
Time = db.Column("Time", db.Time)
DateTime = db.Column("DateTime", db.String)

def __init__(self, HumidityRoots, Date=None, Time=None, DateTime=None):
self.HumidityRoots = HumidityRoots
if Date is None:
Date = str(datetime.now()).split('.')[0]
self.Date = Date
if Time is None:
Time = str(datetime.now()).split('.')[0]
self.Time = Time
if DateTime is None:
DateTime = repr(datetime.now().replace(second=0, microsecond=0)).split('datetime.datetime',1)[1]
self.DateTime = DateTime


@app.route('/Sensors')
def sensors_function():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("GETSENSORS".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/OutputsState')
def outputs_state_function():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("GETOUTPUTSSTATE".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/WebModeState')
def web_mode_state_function():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("GETWEBMODE".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/PLCState')
def plcstatefunction():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("GETPLCSTATE".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/IrrigateOnOff')
def irrigate_on_off_function():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("IRRIGATEOnOff".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/SprinklersOnOff')
def sprinklers_on_off_function():
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto("SprinklersOnOff".encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return rec_data

@app.route('/SetDateTime' , methods=['POST'])
def set_date_time_function():
completeAnswer = "%s:%s:%s:%s:%s:%s:%s:%s" % ("SETDATETIME", request.form.get('dOw'), request.form.get('SetDate'), request.form.get('SetMonth'), request.form.get('SetYear'), request.form.get('SetHour'), request.form.get('SetMinute'), request.form.get('SetSeconds'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetIrrigation' , methods=['POST'])
def set_irrigation_function():
completeAnswer = "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s" % ("SETIRRIGATION",request.form.get('SetIrrigationMode'), request.form.get('SetHumidityRangeMin'), request.form.get('SetHumidityRangeMax'), request.form.get('SetHour1'), request.form.get('SetHour1OnTime'), request.form.get('SetHour1OffTime'), request.form.get('SetHour2'), request.form.get('SetHour2OnTime'), request.form.get('SetHour2OffTime'), request.form.get('SetHour3'), request.form.get('SetHour3OnTime'), request.form.get('SetHour3OffTime'), request.form.get('SetHour4'), request.form.get('SetHour4OnTime'), request.form.get('SetHour4OffTime'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetEC' , methods=['POST'])
def set_EC_function():
completeAnswer = "%s:%s:%s:%s:%s" % ("SETEC", request.form.get('SetECRangeMin'), request.form.get('SetECRangeMax'), request.form.get('SetDoseEC'), request.form.get('SetECDelay'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetPH' , methods=['POST'])
def set_PH_function():
completeAnswer = "%s:%s:%s:%s:%s:%s" % ("SETPH", request.form.get('SetPHRangeMin'), request.form.get('SetPHRangeMax'), request.form.get('SetDosePHUp'), request.form.get('SetDosePHDown'), request.form.get('SetPHDelay'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetWaterTemp' , methods=['POST'])
def set_water_temp_function():
completeAnswer = "%s:%s:%s" % ("SETWATERTEMP", request.form.get('SetWaterTempRangeMin'), request.form.get('SetWaterTempRangeMax'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetSprinklers' , methods=['POST'])
def set_sprinklers_function():
completeAnswer = "%s:%s:%s:%s:%s" % ("SETSPRINKLERS", request.form.get('SetSprinklersBeginEndHoursBegin'), request.form.get('SetSprinklersBeginEndHoursEnd'), request.form.get('SetSprinklersOnTime'), request.form.get('SetSprinklersOffTime'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/SetAlerts' , methods=['POST'])
def set_alerts_function():
completeAnswer = "%s:%s:%s:%s:%s:%s" % ("SETALERTS", request.form.get('SetIrrigationThresholdAlert'), request.form.get('ECAlertOffset'), request.form.get('PHAlertOffset'), request.form.get('ResetCounterState'), request.form.get('AlertsState'))
address= ( '192.168.0.196', 5000) #define server IP and port
client_socket =socket(AF_INET, SOCK_DGRAM) #Set up the Socket
client_socket.settimeout(1) #Only wait 1 second for a response
client_socket.sendto(completeAnswer.encode(), address) #Send the data request
rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino
return "ok"

@app.route('/')
def index():
return render_template('index.html')

@app.route('/Charts')
def charts():
return render_template('charts.html')

@app.route('/livechart')
def live_chart():
return render_template('livechart.html')

@app.route('/TempQuery' , methods=['POST'])
def temp_query():
answerDate = request.form.get('date')
answerSensor = request.form.get('sensor')
datafile = 'temp/TempByDateDbFile.txt'
if answerSensor == 'Temp':
DbTemp = Temp.query.filter_by(Date = answerDate).all()
## create the file from db
file = open(datafile, 'w')
for item in DbTemp:
file.write('{x: new Date' + str(item.DateTime) + ' , y: ' + str(item.Temp) + '},' + '\n')
file.close()
elif answerSensor == 'EC':
DbTemp = EC.query.filter_by(Date = answerDate).all()
## create the file from db
file = open(datafile, 'w')
for item in DbTemp:
file.write('{x: new Date' + str(item.DateTime) + ' , y: ' + str(item.EC) + '},' + '\n')
file.close()
elif answerSensor == 'PH':
DbTemp = PH.query.filter_by(Date = answerDate).all()
## create the file from db
file = open(datafile, 'w')
for item in DbTemp:
file.write('{x: new Date' + str(item.DateTime) + ' , y: ' + str(item.PH) + '},' + '\n')
file.close()
elif answerSensor == 'Humidity':
DbTemp = Humidity.query.filter_by(Date = answerDate).all()
## create the file from db
file = open(datafile, 'w')
for item in DbTemp:
file.write('{x: new Date' + str(item.DateTime) + ' , y: ' + str(item.Humidity) + '},' + '\n')
file.close()
elif answerSensor == 'HumidityRoots':
DbTemp = HumidityRoots.query.filter_by(Date = answerDate).all()
## create the file from db
file = open(datafile, 'w')
for item in DbTemp:
file.write('{x: new Date' + str(item.DateTime) + ' , y: ' + str(item.HumidityRoots) + '},' + '\n')
file.close()
##replace "-" in ","
f = open(datafile,'r')
filedata = f.read()
f.close()
newdata = filedata.replace("-",", ")
f = open(datafile,'w')
f.write(newdata)
f.close()
return 'OK'

@app.route('/RenderTempChart' , methods=['POST' , 'GET'])
def render_temp_chart():
datafile = 'temp/TempByDateDbFile.txt'
with open(datafile, 'r') as myfile:
file = myfile.read()
return render_template('DbTemp.html', file = file)

@app.route('/Control' , methods=['POST' , 'GET'])
def control():
return render_template('control.html')
"""
def update_data(interval): # store in DB all sensors real time data
Timer(interval, update_data, [interval]).start()
SensorsAnswer = sensors_function().split()
addTemp = Temp(int(SensorsAnswer[2]))
addEC = EC(float(SensorsAnswer[0]))
addPH = PH(float(SensorsAnswer[1]))
addHumidity = Humidity(int(SensorsAnswer[3]))
addHumidityRoots = HumidityRoots(int(SensorsAnswer[5]))
db.session.add(addTemp)
db.session.add(addEC)
db.session.add(addPH)
db.session.add(addHumidity)
db.session.add(addHumidityRoots)
db.session.commit()

update_data(300) # Store data in DB every x seconds
"""
if __name__ == "__main__":
app.run()

即使使用这样的简单代码也无法正常工作(相同的错误):

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
return "Hello world!"

if __name__ == "__main__":
app.run()

我正在使用 python 3.4.2。我没有在虚拟环境中使用它。

文件夹结构:

app.py 位于 /var/www/Arduinoweb/Arduinoweb/app.pyarduinoweb.wsgi位于/var/www/Arduinoweb/arduinoweb.wsgi

我确实启用了 VirtualHost arduinoweb.conf 并重新启动了 apach2 服务。

最佳答案

首先,这个:

<Directory /var/www/ArduinoWeb/ArduinoWeb>
WSGIProcessGroup arduinoweb
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Require all granted
</Directory>

应该是:

<Directory /var/www/ArduinoWeb>
WSGIProcessGroup arduinoweb
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>

从技术上讲,这种错误会导致两个问题。

首先,Apache 甚至不应该让您使用该 WSGI 脚本,因为它没有权限。看起来 Apache 配置中的其他地方正在为您的文件系统提供广泛的访问权限,而实际上本不应该这样做。

我还删除了重新加载选项,因为该选项默认为打开并且不需要。

第二个是 WSGI 脚本不会在守护进程进程组的上下文中运行。这意味着代码将以嵌入模式加载并以 Apache 用户身份运行。如果您的文件的权限只有 pi 用户可以读取它们,那么它将无法访问 app 模块。

SeverName 设置为 IP 地址通常也是错误的。如果它正在工作,那么它只是这样做,因为这是 Apache 配置中的第一个 VirtualHost,因此 Apache 在无法正确进行名称基础虚拟主机匹配时默认使用它。

无论如何,看看这是否有帮助,否则提供运行的输出:

ls -las /var/www/ArduinoWeb /var/www/ArduinoWeb/ArduinoWeb

这样可以检查目录/文件的所有权/权限是什么。

关于apache - 使用 mod_wsgi 在 Apache 上部署 Flask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39624584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com