在1& 1共享主机(使用CGI)上部署烧瓶应用程序

时间:2013-08-15 18:41:23

标签: python cgi flask

我用烧瓶网框架为我的体育俱乐部写了一个网络应用程序。我使用内置测试服务器在本地计算机上完成了所有操作。

知道他们告诉我将其部署在1& 1共享主机网站空间。他们有python支持,但似乎他们只允许CGI运行python脚本。

我尝试了这个教程:flask via CGI

到目前为止,我忽略了重写的内容。对我的CGI脚本的所有请求都导致404错误。我修改了应用程序中的404处理程序以返回request.path。当我请求/foo/runserver.cgi/时,它返回/作为输出。我不知道它为什么不提供索引视图。它不适用于任何视图,我总是得到404。

亲切的问候, 塞巴斯蒂安

3 个答案:

答案 0 :(得分:17)

我写了近一年后提供答案,因为给出的答案是不完整的,因为建议放弃/ $ 1是错误的。使用字符串“deploy flask on cgi”通过Internet搜索可以到达的其他stackoverflow线程也没有令人满意的解决方案。

首先,我的.htaccess文件与引用的“flask via CGI”文档完全相同,只是必须删除RewriteCond第二行中的注释,因为在.htaccess中,任何注释都必须占用整行。

我将.htaccess文件放在public_html文档根文件夹中,我的cgi脚本是/home/myusername/public_html/scgi-bin/moc/cgiappserver-prod.cgi。

它当然是Python,顶部的shebang最好是对的。在我的ISP,他们使用cpanel,它有一个CGI包装器,他们称之为“scgi”。不幸的是,它不是the real thing。因此,为了运行Flask,将其视为普通的CGI。

我应该补充一点,我只有一个共享托管帐户。

这是我的cgiappserver-prod.cgi文件:

#!/home/myusername/local/bin/python
import cgitb; cgitb.enable()  # This line enables CGI error reporting
from wsgiref.handlers import CGIHandler
import traceback
from settings import LGGR

app = None
try:
    import moc
    app = moc.app
except Exception, e:
    LGGR.info( traceback.format_exc([10]) )
    LGGR.info( 'Problem in cgiappserver-prod with moc import: %s' % e )

class ScriptNameStripper(object):
   def __init__(self, app):
       self.app = app
   def __call__(self, environ, start_response):
       environ['SCRIPT_NAME'] = ''
       return self.app(environ, start_response)

app = ScriptNameStripper(app)

try:
    CGIHandler().run(app)
except Exception, e:
    LGGR.info( traceback.format_exc([10]) )
    LGGR.info( 'Problem in cgiappserver-prod with CGIHandler().run(): %s' % e )

所以我的应用程序分布在几个文件中,特别是在上面的代码中显示了setting.py和moc.py。

我的徘徊时间部分是由于我读过的关于这个主题的所有无用帖子,但主要是因为我没有及早收到错误消息的业务。 (我可以访问ISP提供的错误日志,但它很少有用。)

首先,我确认cgitb.enable()函数有效。我故意拼写错误的wsgiref并看到一个漂亮的错误页面,我已经注释掉了cgitb(cgi traceback)行,看到错误信息变成了无用的500状态代码。

请注意,我还在settings.py中设置了一个记录器,一个旋转文件记录器LGGR。有了它,我发现我必须做一些额外的事情 - 这里没有显示---告诉Python解释器sqlite3库的位置。

另外,您可以简单地使用print语句,CGI上引用的Flask文档说明了这些语句:

  • 使用CGI,您还必须确保您的代码没有 包含任何打印语句,或者覆盖sys.stdout 不写入HTTP响应的东西。

这是真的,但在调试时看到有用以查看打印写入HTTP响应。

最后,当我最终得到它时,浏览器的位置框遗憾地有像www.mysite.com/scgi-bin/moc/cgiappserver-prod.cgi/contact这样的东西,而我真的只需要www。 mysite.com/contact。

治愈是cgiappserver-prod.cgi中的ScriptNameStripper类。我是从other Flask docs得到的。

答案 1 :(得分:3)

我找到了解决方案!我将/$1远离.htaccess并稍微修改了werkzeug,因为CGI中的环境变量与WSGI应用程序中的环境变量略有不同。我会告诉werkzeug开发人员,可能会将我的解决方案包含在werkzeug中。

答案 2 :(得分:2)

我会尝试展示我已做过的事情,并且它正在Godaddy分享主持人帐户中工作:

在MYSITE文件夹的cgi-bin文件夹中,我添加了以下cgi文件:

#!/home/USERNAME/.local/bin/python3
from wsgiref.handlers import CGIHandler

from sys import path
path.insert(0, '/home/USERNAME/public_html/MYSITE/')
from __init__ import app

class ProxyFix(object):
   def __init__(self, app):
       self.app = app

   def __call__(self, environ, start_response):
       environ['SERVER_NAME'] = ""
       environ['SERVER_PORT'] = "80"
       environ['REQUEST_METHOD'] = "GET"
       environ['SCRIPT_NAME'] = ""
       environ['PATH_INFO'] = "/"
       environ['QUERY_STRING'] = ""
       environ['SERVER_PROTOCOL'] = "HTTP/1.1"
       return self.app(environ, start_response)

if __name__ == '__main__':
    app.wsgi_app = ProxyFix(app.wsgi_app)
    CGIHandler().run(app)

正如您所看到的,MYSITE文件夹中的 init 文件包含烧瓶应用程序。

最重要的是设置权限。我将755设置为此文件夹权限,以及" /home/USERNAME/.local/bin/python3"夹!!请记住,系统需要此权限才能打开flask和所有python包。

为了进行调试,我建议您通过ssh终端访问您的网站,然后单独运行CGI。如果它有效,但在网络上没有,这意味着您可能需要提供更多权限,或者您写错了.htaccess文件。

要打开cgi,我在MYSITE文件夹中有以下.htaccess文件:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ /home/USERNAME/public_html/MYSITE/cgi-bin/application.cgi/$1 [L]

因此,当有人进入您的页面时,它会呈现cgi文件。