【问题标题】:Getting correct path to static files to serve them through nginx获取静态文件的正确路径以通过 nginx 为它们提供服务
【发布时间】:2020-09-15 04:04:44
【问题描述】:

我无法弄清楚如何通过 Nginx 和 Gunicorn 为我的 Flask Web 应用程序提供静态文件。我在网上看到的所有文档都指向当客户端请求静态文件时添加一些静态文件夹别名的路径。但是,我不确定完整路径应该是什么,因为该应用程序托管在 Heroku 上。所有对静态文件的请求都返回 404 错误。我还注意到,对存储在目录路径/static/json/<file>.json 中的 JSON 文件的 XHR 请求在成功时没有返回 JSON 对象。

项目层次结构:

project/
|_ config/
   |_ gunicorn.conf.py
   |_ nginx.conf.erb
|_ flask_app/
   |_ __init__.py
   |_ static/
      |_ css/
      |_ js/
      |_ images/
      |_ json/
|_ Procfile
|_ run.py

项目/配置/gunicorn.conf.py:

def when_ready(server):
    open('/tmp/app-initialized', 'w').close()

bind = 'unix:///tmp/nginx.socket'

项目/配置/nginx.conf.erb:

daemon off;
#Heroku dynos have at least 4 cores.
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;

events {
    use epoll;
    accept_mutex on;
    worker_connections <%= ENV['NGINX_WORKER_CONNECTIONS'] || 1024 %>;
}

http {
    server_tokens off;

    log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
    access_log <%= ENV['NGINX_ACCESS_LOG_PATH'] || 'logs/nginx/access.log' %> l2met;
    error_log <%= ENV['NGINX_ERROR_LOG_PATH'] || 'logs/nginx/error.log' %>;

    include mime.types;
    default_type application/octet-stream;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    #Must read the body in 5 seconds.
    client_body_timeout 5;

    upstream app_server {
        server unix:/tmp/nginx.socket fail_timeout=0;
    }

    server {
        listen <%= ENV["PORT"] %>;
        server_name _;
        keepalive_timeout 5;

        # Configure NGINX to deliver static content from the specified folder
      location /static {
        alias /static;
      }

        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://app_server;
        }
    }
}

项目/过程文件

web: bin/start-nginx gunicorn -c config/gunicorn.conf.py 'run:create_app()'
worker: python worker.py
clock: python clock.py

example.js

export function getData() {
  $.ajax({
    type: 'GET',
    url: '/static/json/data.json',
    async: false,
    success : function(data) {
      currentPageIndex = 0;
      numberOfPages = data.length; // Getting undefined error here on "data"
    }
  });
}

【问题讨论】:

  • 它在你的本地主机上工作吗?您的静态文件存储在哪个文件夹中?
  • Heroku 将 git 根文件夹放入其文件系统上的 /app
  • 我更新了我的项目层次结构,静态文件存储在静态目录中。因此,如果 Herky 将根文件夹置于 /app 是否意味着 Nginx 配置文件应该有 location /app/flask_app/static {} 而不是 location /static {}
  • 要回答你关于它是否在 localhost 中工作的问题,是的,但那是因为 Flask 在开发环境中的 Werkzeug 上运行,所以我无法在 Nginx 上对其进行测试。而且我无法在 localhost 上的生产环境中测试它,因为我没有浏览器可以识别的 localhost 证书,因为生产环境使用 HTTPS。

标签: nginx flask heroku static gunicorn


【解决方案1】:

在您给定的配置中,有(至少)两种托管静态内容的方式。我不清楚您决定以下两种选择中的哪一种-我的印象是您想以某种方式同时拥有两者?

  1. 我相信你读过https://flask.palletsprojects.com/en/1.1.x/tutorial/static/ 上面写着

    Flask 会自动添加一个静态视图,该视图采用相对于 flaskr/static 目录的路径并为其提供服务。

    URL 将与您的烧瓶 SPA 相同,后面有一个额外的 static,请参见例如Link to Flask static files with url_forhttps://flask.palletsprojects.com/en/1.1.x/quickstart/#url-building

    静态内容的文件位置将是您的 flask-app-directory 中的 /static

  2. 还请注意How to serve static files in Flask 上面写着

    首选方法是使用 nginx 或其他 Web 服务器来提供静态文件;他们将能够比 Flask 更有效地做到这一点。

    在这种情况下,Nginx docu on Serving Static Content 是您的朋友:

    URL 就是www.example.com/whateverHerokuPutsHere/static

    文件位置可以是您在nginx.conf 中指定的任何内容,通常可以将绝对路径放在那里。

    免责声明:我从未与heroku 合作过,所以我不确定是否真的会有whateverHerokuPutsHere。很可能它只是example.com,因为您在 Heroku 的 UI 上的某个位置进行了配置。对于我找到的文件位置a blog Nginx as a static site server on Heroku

【讨论】:

  • 这基本上是我为我的烧瓶应用程序尝试遵循的教程:medium.com/@eserdk/heroku-nginx-gunicorn-flask-f10e81aca90d。问题是本教程中所述的代码不适用于如何通过 Nginx 提供静态文件。我也用上面的代码尝试过,但 Heroku 日志告诉我静态目录不正确,因此没有从 HTTP 响应加载内容。我要做的是通过 Nginx 为我的网络应用程序和静态文件提供服务,以便改进加载。
  • 明白。您基本上选择选项 2。在大多数情况下,这是一个文件或目录权限问题,它避免了 nginx 提供文件,i.a.w. /static 应该是世界可读的。你仔细检查了吗?
  • 那么我应该强制 Nginx 配置文件中的服务器监听 80 端口吗?所以把这行listen &lt;%= ENV["PORT"] %&gt;;改成listen 80;?我只是不知道正确设置静态路径需要做什么。您提到的帖子显示,在location /static {} 中,用户将根路径设置为静态文件夹,在 Heroku 上对我来说是 /app/flask_app/static/。
  • 我更新了我的项目层次结构,如果这有助于我正在寻找的东西。
  • 作为一个实验:请将nginx配置中的alias static更改为alias /flask_app/static或相应的完整路径,好吗?
【解决方案2】:

使用python代码渲染文件

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

examples/flask/stat/templates/main.html

如果您使用静态图片 使用相对路径

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport"
     content="width=device-width, initial-scale=1, user-scalable=yes">

  <link href="/static/css/style.css" rel="stylesheet">
</head>
<body>
<h1>Hello World</h1>

<img src="static/img/code_maven_128.png" />

</body>
</html>

The CSS itself is also very simple, its content is not relevant for our purposes.

examples/flask/stat/static/css/style.css

h1 { 颜色:蓝色; } 如何运行这个 有两种简单的方法可以在 developerlent 中运行它。对于这两种情况,您都需要打开终端(如果您在 Windows 上,则为 cmd 窗口),切换到可以找到应用程序文件(在本例中为 web.py)的目录。

python web.py 一种更好的方法是使用:

https://code-maven.com/flask-serve-static-files

enter code here

【讨论】:

    【解决方案3】:

    我发现问题与别名路径不正确有关。一开始很难确定,因为 Heroku 的根目录设置与我在本地机器上的设置不同。 Heroku 应用程序的根目录是/app,所以我根据我的项目层次结构将别名更改为这个。这应该适用于其他面临类似问题的人。

    location /static {
       alias /app/flask_app/static;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2015-03-18
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 2010-12-01
      • 2021-06-20
      相关资源
      最近更新 更多