Nginx代理到本地磁盘或S3上的文件

Coo*_*mer 13 proxy nginx amazon-s3

所以我将我的网站从Apache转移到Nginx,我遇到了这个场景的问题:

用户上传照片.此照片已调整大小,然后复制到S3.如果磁盘上有合适的空间(或者文件无法传输到S3),则保留本地版本.

我想要请求这些图像(例如http://www.mysite.com/p/1_1.jpg)首先查看p /目录.如果不存在本地文件,我想将请求代理到S3并呈现图像(但不是重定向).

在Apache中,我这样做:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^p/([0-9]+_[0-9]+\.jpg)$ http://my_bucket.s3.amazonaws.com/$1 [P,L]
Run Code Online (Sandbox Code Playgroud)

我试图在Nginx中复制这种行为是这样的:

location /p/ {
    if (-e $request_filename) {
        break;
    }
    proxy_pass http://my_bucket.s3.amazonaws.com/;
}
Run Code Online (Sandbox Code Playgroud)

会发生什么事情是每个请求都尝试命中Amazon S3,即使该文件存在于磁盘上(如果它在亚马逊上不存在,我也会收到错误.)如果我删除了proxy_pass行,那么磁盘DO上的文件请求就会起作用.

有想法该怎么解决这个吗?

Dan*_*yle 33

这不应该是一个使用的例子try_files吗?

location /p/ {
    try_files $uri @s3;
}

location @s3{ 
    proxy_pass http://my_bucket.s3.amazonaws.com;
}
Run Code Online (Sandbox Code Playgroud)

确保S3网址上没有以下斜杠


小智 12

您可以像这样改进您的s3代理配置.改编自/sf/answers/3132470911/:

location /p/ {
    try_files $uri @s3;
}

location @s3 {
  set $s3_bucket        'your_bucket.s3.amazonaws.com';
  set $url_full         '$1';

  proxy_http_version     1.1;
  proxy_set_header       Host $s3_bucket;
  proxy_set_header       Authorization '';
  proxy_hide_header      x-amz-id-2;
  proxy_hide_header      x-amz-request-id;
  proxy_hide_header      x-amz-meta-server-side-encryption;
  proxy_hide_header      x-amz-server-side-encryption;
  proxy_hide_header      Set-Cookie;
  proxy_ignore_headers   Set-Cookie;
  proxy_intercept_errors on;

  resolver               8.8.4.4 8.8.8.8 valid=300s;
  resolver_timeout       10s;
  proxy_pass             http://$s3_bucket$url_full;
}
Run Code Online (Sandbox Code Playgroud)