Offerta di immagini memorizzate nella cache dinamicamente da nginx
Voglio servire le miniature per le immagini e queste miniature vengono generate su richiesta, scritte su disco, quindi le voglio passare a nginx per essere pubblicate.
La mia cartella principale per le miniature è /var/www/images. Quando ricevo una richiesta /thumb/post1/image1.jpg, desidero elaborarla in questo modo:
- Se l'immagine è presente
/var/www/images/thumb/post1/image1.jpg, servila direttamente. - Se l'immagine non è presente, deve essere generata, quindi passa la richiesta all'API all'indirizzo
@backend. - L'API genera l'immagine e la scrive nella cartella delle miniature, quindi restituisce il percorso a nginx utilizzando
X-Accel-Redirectun'intestazione. - nginx riavvia l'elaborazione al passaggio 1, che avrà esito positivo perché il file è ora presente.
- Se l'elemento per cui è stata richiesta la miniatura non esiste, l'API restituirà un 404 e nginx dovrebbe pubblicare un'immagine segnaposto situata in
/var/www/images/missing.png.
La mia configurazione di nginx è simile a questa:
upstream api {
server localhost:7440 fail_timeout=0;
}
server {
root /var/www/www.example.com/public;
location / {
try_files $uri @backend; } location /thumb { root /var/www/images; try_files $uri @backend /missing.png;
}
location @backend {
root /var/www/api.example.com/public;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://api;
#For websocket compatibility
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Le mie miniature sono mantenute fuori dalla cartella del progetto, quindi ho bisogno di una rootdirettiva nella /thumbposizione per far sì che cerchi l'immagine. La /posizione gestisce le richieste API e altri asset statici e la /thumbposizione fa lo stesso, ma ha anche il fallback a missing.png.
Una stranezza: per ragioni storiche la mia rootcartella complessiva non è la stessa di quella utilizzata dalla mia @backendposizione denominata, tuttavia, la sovrascrivo in entrambe le locationdirettive e non esiste un livello superiore try_files.
Tuttavia, questo non funziona. Le richieste di immagini mancanti non vengono inviate all'API, ma un fallback per un'immagine mancante sì! Se rimuovo il fallback, le richieste non vengono inviati alle API, ma poi l'handoff a x-accel-redirectnon riesce, anche se il file esiste ora; quando l'immagine del pollice esiste, nginx non la pubblica: colpisce di nuovo l'API.
Come dovrebbe essere configurato?
Risposte
La tua try_filesdichiarazione non è corretta, la posizione denominata deve essere l'ultimo parametro. Inoltre, la risposta 404 è generata dal location @backendblocco e non ha nulla a che fare con l' try_filesistruzione nel location /thumbblocco.
Si dovrebbe cercare proxy_intercept_errorse error_pageper gestire la risposta 404 dal backend.
Per esempio:
location / {
try_files $uri @backend1; } location /thumb { root /var/www/images; try_files $uri @backend2;
}
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location @backend1 {
proxy_pass http://api;
}
location @backend2 {
proxy_intercept_errors on;
error_page 404 /missing.png;
proxy_pass http://api;
}