proxy amazon-s3 nginx

Proxy Nginx para archivos en disco local o S3



amazon-s3 (5)

Así que estoy moviendo mi sitio de Apache a Nginx, y estoy teniendo problemas con este escenario:

El usuario carga una foto. Esta foto se redimensiona y luego se copia a S3. Si hay espacio adecuado en el disco (o el archivo no se puede transferir a S3), se guarda una versión local.

Quiero que las solicitudes de estas imágenes (como http://www.misitio.es/p/1_1.jpg ) se vean primero en el directorio p /. Si no existe ningún archivo local, quiero enviar la solicitud por proxy a S3 y renderizar la imagen (pero no redirigir).

En Apache, hice esto así:

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

Mi intento de replicar este comportamiento en Nginx es este:

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

Lo que sucede es que cada solicitud intenta golpear Amazon S3, incluso si el archivo existe en el disco (y si no existe en Amazon, obtengo errores). Si elimino la línea proxy_pass, entonces las solicitudes de archivos en el disco funcionan. .

¿Alguna idea sobre cómo solucionar este problema?


¿No debería ser esto un ejemplo de usar try_files ?

location /p/ { try_files $uri @s3; } location @s3{ proxy_pass http://my_bucket.s3.amazonaws.com; }

Asegúrese de que no haya una barra oblicua en la URL S3


Gracias a keep my coderwall post :) Para el propósito de almacenamiento en caché puedes mejorarlo un poco:

http { proxy_cache_path /tmp/cache levels=1:2 keys_zone=S3_CACHE:10m inactive=24h max_size=500m; proxy_temp_path /tmp/cache/temp; server { location ~* ^/cache/(.*) { proxy_buffering on; proxy_hide_header Set-Cookie; proxy_ignore_headers Set-Cookie; ... proxy_cache S3_CACHE; proxy_cache_valid 24h; proxy_pass http://$s3_bucket/$url_full; } } }

Una recomendación más es extender la caché de resolución hasta 5 minutos:

resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s;


Podrías mejorar tu configuración de proxy s3 así. Adaptado de https://.com/a/44749584 :

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; }


Terminé resolviendo esto comprobando para ver si el archivo no existe, y si es así, reescribiendo esa solicitud. Luego manejo la solicitud reescrita y hago el proxy_pass allí, así:

location /p/ { if (!-f $request_filename) { rewrite ^/p/(.*)$ /ps3/$1 last; break; } } location /ps3/ { proxy_pass http://my_bucket.s3.amazonaws.com/; }


break no está haciendo lo que esperas. nginx hará lo último que le pidas, lo que tiene sentido si comienzas a buscar módulos ... pero básicamente protege tu proxy_pass con la versión de no-existir.

if (-f $request_filename) { break; } if(!-f $request_filename) proxy_pass http://s3; }