【问题标题】:flask templates works in local env but return error 404 under nginx烧瓶模板在本地环境中工作,但在 nginx 下返回错误 404
【发布时间】:2016-03-22 23:32:18
【问题描述】:

我已阅读答案 [https://stackoverflow.com/a/20895594/305883],但对我没有帮助。

我有一个烧瓶应用程序,可以在 localhost 中提供模板或在端点 /path/<int:id>/ 进行调试,但在使用 nginx 的生产环境中它会失败 带有 错误 404

Flask 项目具有默认结构:

app.py
index.html
/templates/mytemplate.html
/static/..

mytemplate.html 将从/static/ 文件夹加载资源,使用 jinja 语法。

已编辑

目标:我希望应用服务:

  • root / 将提供 index.html

  • /path/ 将打开“myTemplate.html”并用变量填充它 (神社);如果可能的话,我希望模板中包含静态资产(例如 js, css, images) 由 nginx 提供服务;

  • /api/ 将提供 api rest。

在我的本地环境中,我使用的是烧瓶服务器,而不是 ningx,并且三个端点按预期工作。

在生产中,我使用烧瓶和 ningx。 根和 /api/ 边缘工作; /path/ ,用于烧瓶中的模板,不返回 error 404

为了设置 nginx,我按照本教程中的步骤操作: [https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-14-04]

flask 中的模板由以下人员提供服务:

@application.route('/path/<int:id>/')
def graph_template(id):
    meta = {'og:image':'/url/image.jpg'}
    try:
        key = decode(id)[0]
    except:
        # todo replace with error 400
        return jsonify({'error':'Something got wrong. ID not found'})
    return render_template('mytemplate.html', meta=meta, id = id)

我在调试和发现问题时遇到困难,使/path/显示模板。

nginx 配置

server {
    listen 80;

    #  is this block to serve index on root only ?
    #  or will search for index files also in routes /path/ in ningx and/or flask? 
       root /var/www/mySite;
        index index.html index.htm;

        location /api {
    #       try_files $uri $uri/ /index.html;
            include uwsgi_params;
            uwsgi_pass unix:/var/www/mySite/myApp.sock;

    #        auth_basic "API Login";
    #        auth_basic_user_file /etc/nginx/pw_file;
    #        allow 127.0.0.1;
    #       allow XX.XX.XXX.XXX;
    #        deny all;
        }

    location /static {
    alias /var/www/mySite/static;
    }

}

我尝试了以下方法:

包括一个proxy_pass:

location / {
   proxy_pass http://127.0.0.1:8080; 
}

结果:导致错误 502

尝试将端口更改为:80

location / {
   proxy_pass http://127.0.0.1:80; 
}

结果:错误 404

尝试在 /path/ 端点使用 uwsgi_pass 套接字

location /path/ {
   include uwsgi_params;
   uwsgi_pass unix:/var/www/mySite/myApp.sock; 
}

结果:这条路线不存在http://example.com/path/ 我不明白,因为烧瓶应该在这里提供模板 - 至少不是错误配置错误 502。

回答:[Python Flask server crashing on GET request to specific endpoint: 为每个端点显示了两个套接字 - 我需要使用这样的设置吗? 我正在尝试记录自己的套接字是什么并使用 nginx 文档,但很抱歉,我在这方面的能力不强,而且我在黑暗中移动了一点。

您能帮忙调试一下问题吗?

【问题讨论】:

    标签: python templates nginx flask http-status-code-404


    【解决方案1】:

    耶!我自己找到了答案:

    在 nginx 中添加此块可用于使用 nginx 从烧瓶中提供模板

    location /path/ {
       include uwsgi_params;
       uwsgi_pass unix:/var/www/mySite/myApp.sock; 
    }
    

    其中/path/ 是模板的端点。

    我收到上面的消息是因为烧瓶实际上正在处理 404 错误,因为我写了我的装饰器来点击 /path/&lt;int:id&gt; 并处理 404 请求:

    @application.errorhandler(404)
    def page_not_found(error):
        return 'This route does not exist {}'.format(request.url), 404
    

    但是,如果有人可以添加一些 cmets 来解释烧瓶和 nginx 之间的路由实际上是如何工作的,以及使用 uwsgi_passproxy_pass 之间的区别(我在不同的教程中找到),我将非常感激,并且套接字的使用(我遵循的教程)。

    例如,在这个问题 [Python Flask server crashing on GET request to specific endpoint: 中,用户为每个端点使用两个套接字,对于初学者来说,我认为这可能是问题所在,但事实并非如此。

      1234563 /static/文件夹)
    • 是否有更好的配置来利用 ningx 提供烧瓶模板的功能?

    最受赞赏的评论!

    【讨论】:

      【解决方案2】:

      我假设您的 本地环境 可以在没有 nginx 的情况下工作,对吗?那么,让我们来看看:

      在本地环境中,点击/path/(没有id)会返回url not found的错误,没关系。相反,在 prod 环境中,nginx 将搜索 /path/index.html - 虽然我在烧瓶装饰器中没有提到。

      查看nginx 配置的第三行。在那里,您指定nginx 应查找index.html

      在本地环境中,如果我点击/path/id/ 它可以正常工作。在生产环境中,它返回错误 404,no such file or directory

      我认为,这是因为您没有将任何流量传递给您的 flask app。你需要一些类似的东西:

      location / {
        proxy_pass http://127.0.0.1:8080; #Change to match your environment
      }
      

      您缺少这些(如果没有,请显示您的整个nginx 配置),因此nginx 将在您的存储中搜索静态文件。但是,这些请求不能由静态文件提供服务,而是您的 backend(又名您的 flask app)必须动态呈现和创建这些请求。为此,您必须将流量发送到那里。

      我没有发现由于 /static/ 文件夹中的资源失败而导致的错误(例如,在许可中);看起来烧瓶无法加载或被允许提供模板。

      浏览器可以在/mysite/templates/mytemplate.html加载模板文件静态文件夹权限设置为403,但/static/js/file.js会被读取。

      对不起,我不明白。能详细点吗?

      【讨论】:

      • Hi @gf_ in local env 没问题。在我的 ningx 配置中,我仅在 root 中提供 index.html,请参阅更新。关于将流量传递给烧瓶:我尝试添加并立即返回502 error;但是在 nginx error.log 上没有额外的解释。应该匹配服务器监听的80端口吗? Flask 正确地为 API 端点提供服务,而不是模板 - 可以让 flask 完成 jinja 块并让 nginx 提供最终的 html 文件吗?
      • 不知道“应该匹配服务器监听的端口 80”是什么意思。请编辑您的问题 ahd 明确 状态,哪些请求有效,哪些无效。除此之外,请描述你的local env:这和production有什么区别?关于您的nginx 配置:您正在将流量传递给套接字:此套接字是否存在?它是否指向您的flask app?如果是这样,您必须相应地更改我给定的示例:将 proxy_pass 指令更改为您的 uwsgi_pass 一个..并注意我的评论阅读“更改以匹配您的环境”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 2018-03-02
      • 2015-12-27
      • 2021-01-01
      • 2021-10-27
      • 2017-04-20
      相关资源
      最近更新 更多