2016-09-21 11 views
1

私はApacheサーバー上で動作するように構築されたFlask Webアプリケーションをデプロイしようとしています。 私はrasberry pi 3でrasbian(Jessie)OSを使用しています。フラスコの完璧なランニング アプリは内蔵のdevのWebサーバが、私はapachにデプロイするために管理しhaventは何nomatther、これは私がやったことです:mod_wsgiを使用して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:[email protected]/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() 

そのこのような単純なコード(同じエラー)にしても動作しない:私のpython 3.4.2を使用してい

from flask import Flask 

app = Flask(__name__) 

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

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

。私は仮想環境でそれを使用していません。

フォルダ構造:

app.py/var/www/Arduinoweb/Arduinoweb/app.py arduinoweb.wsgiであるが/var/www/Arduinoweb/arduinoweb.wsgi

で私はのVirtualHost arduinoweb.confを有効にしてapach2サービスを再起動しないです。

+0

SElinuxを実行していますか? – seanmus

+0

必要なディレクトリに '__init __。py'がありますか?アプリがシンプルフラスコ開発サーバーで動作している場合、 – seanmus

+0

は__init__.pyが見つからないことがありますか? –

答えて

1

開始するために、この:

<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設定のどこか他の場所のように見えますが、実際にはいけないときにファイルシステムに広範にアクセスできるようになりました。

私はまた、デフォルトのままリロードオプションをとにかく削除しているので、必要ありません。

2つめは、WSGIスクリプトがデーモンプロセスグループのコンテキストで実行されないことです。これは、コードが組み込みモードで読み込まれ、Apacheユーザーとして実行されることを意味します。あなたのファイルのパーミッションが、piユーザだけが読むことができるようなものであれば、appモジュールにアクセスすることはできません。

SeverNameをIPアドレスにすることは、一般的に間違っています。動作しているのであれば、これはApache構成の最初のVirtualHostであるため、Apacheはデフォルトの仮想ホストのマッチングを正しく実行できないときにApacheをデフォルトで使用しているため、これを実行しているだけです。

ことができます場合はとにかく、そうでない場合は、実行中の出力を提供し、以下を参照してください。

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

ので、ディレクトリ/ファイルの所有権/パーミッションが何であるかを確認することができます。

+0

あなたが書いたものを試してみてください、同じエラー、私は所有権/許可をすべて確認しました –

+0

あなたはあなたが所有権/ :-)彼らが検証するのを見ることを望んでいた。他の誰かが尋ねたように、SELinuxが有効になっているかどうかをチェックしたことがありますか?通常、 ''/var/www''の下にある場合、SELinuxを有効にしていても、Apacheはアクセスしてはいけません。 –

+0

4 drwxrwxrwx 6 pi pi 4096 Sep 24 11:36。 4 drwxrwxrwx 3 pi 4096 9月24 11:04 .. 4 -rwxrwxrwx 1 pi pi 148 Sep 21 20:43 app2.py 16 -rwxrwxrwx 1 pi pi 15405 Sep 24 11:36 app.py 4 drwxr- XR-X 2 WWWデータWWWデータ4096 9月24日11時04 __pycache__ 4 drwxrwxrwx 4のPI、PI 4096 9月10日午後07時18分静 4 drwxrwxrwx 2のPI、PI 4096 9月10日19時18 TEMP 4 drwxrwxrwx 2のPI、PI 4096 Sep 10 19:18 templates –

1

助けてくれてありがとう。最終的には、wsgiスクリプトのパスで "/ var/www/ArduinoWeb/ArduinoWeb"の代わりに "/ var/www/Arduinoweb/Arduinoweb"という入力ミスがあるようです。

現在、正常に動作しているようです。ありがとう!!