flask 模板在本地环境中工作,但在 nginx 下 return 错误 404

flask templates works in local env but return error 404 under nginx

我已阅读答案[,但对我没有帮助。

我有一个 Flask 应用程序,可以在本地主机 中提供模板或在端点 /path/<int:id>/ 进行调试,但在生产中使用 nginx 它会 失败 并出现 错误 404.

Flask 项目具有默认结构:

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

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

已编辑

目标: 我希望应用程序服务:

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

在生产中,我用的是flask和ningx。 根和 /api/ 边缘工作; /path/ ,用于在烧瓶中进行模板化,没有 return 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 文档但抱歉我不擅长它并且我在黑暗中移动了一点。

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

我假设你的 local env 在没有 nginx 的情况下工作,对吧?那么,让我们看看:

In local environment, hitting /path/ (with no id) will return an error of url not found, which is ok. Instead in prod environment, nginx will search for /path/index.html - although I have not mentioned in flask decorator.

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

In local env, if I hit /path/id/ it works ok. In production env, it returns error 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)必须动态呈现和创建这些请求。为此,您必须将流量发送到那里。

I have not found an error due to failing with resources from /static/ folder (e.g. in permission); it looks like flask cannot load or be allowed to serve the templates.

Template file can be loaded by the browser at /mysite/templates/mytemplate.html Static folder permission is set on 403, but /static/js/file.js will be read.

抱歉,我不明白。能详细点吗?

太棒了!我自己找到了答案:

在 nginx 中添加这个块 使用 nginx 从 flask 提供模板:

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

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

我收到上面的消息是因为 flask 实际上正在处理 404 错误,因为我写了我的装饰器来命中 /path/<int:id> 并处理 404 请求:

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

但是,如果有人可以添加一些评论来解释 flask 和 nginx 之间的路由实际上是如何工作的,以及使用 uwsgi_passproxy_pass 之间的区别(我发现在不同的教程中),以及套接字的使用(我遵循的教程)。

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

  • 有了这个配置,我知道 flask 将处理 .html 模板:它是否也处理模板中的资源(js,css)或者它们是否被提供通过 nginx(请参阅上面的配置,所有资产都在 /static/ 文件夹中)

  • 是否有更好的配置来利用 ningx 功能来提供 flask 模板?

评论最多!