X-Accel-Redirect 功能不适用于外部连接(在 docker 网络内)

X-Accel-Redirect feature does not work for external connections (inside docker network)

我正在尝试允许带有 django 的容器管理对从另一个带有 nginx 的容器提供的媒体文件的访问。因此,尽管有 nginx 文档,我还是从位置配置中删除了 internal 行:

server {
    server_name nginx; //name of the container used for accessing from another containers
    charset UTF-8;
    client_max_body_size 32m;
    listen 80;

    location /protected/media/ {
        // internal;
        alias /data/djan,go/media/;
    }
}

通过此配置,我可以使用来自 django 容器的 /protected/media urls,因此我已经成功地使用 django 容器的 shell 执行 wget http://nginx/protected/media/images/bank_credentials/H0grsrvgsBo.jpg .

但是django的代码

response = HttpResponse()
del response['Content-Type']
response['X-Accel-Redirect'] = 'http://nginx/protected/media/' + path # I'm sure that this url matches to url I've used succesfully with wget
return response 

返回 404 这是 django 的 url:

path('media/<path:path>', media_access, name='media')

我哪里错了?

听起来您想要做的是让 X-Accel-Redirect 具有绝对值 URL 作为外部 domain/host,因此需要删除 internal 作为每 http://nginx.org/r/internal 使文件无需身份验证即可访问。不是这样的。

查看 http://nginx.org/r/proxy_pass_request_headers 中提供的示例,例如:

location /x-accel-redirect-here/ {
    proxy_method GET;
    proxy_pass_request_headers off;
    proxy_pass_request_body off;

    proxy_pass ...
}

nginx 要求必须在 X-Accel-Redirect 中使用相对 URLs 是完全合理的;否则,nginx 怎么知道如何准确处理请求?


换句话说,您可能必须在 X-Accel-Redirect 中使用相对 URLs,并且,如果您需要转义到另一个容器中,则需要额外的 internal location 指令执行显式 proxy_pass,视情况而定。

请注意,这样做可能首先会使使用 X-Accel-Redirect 的全部好处失效,尤其是由于 http://nginx.org/r/proxy_buffering 默认为 on,这会导致 nginx 保存每个代理文件到光盘上,因此光盘吞吐量可能很快成为您设置中的限制因素。