Nginx搭配Passenger时无法提供预压缩缓存文件的问题求助
问题
在Nginx搭配Passenger运行Rails应用时,已对部分静态文件启用页面缓存,会在public目录生成.html及预压缩的.html.gz文件。单独使用Nginx时可正常返回.html.gz,但开启passenger_enabled on后,Nginx不再使用预压缩文件,而是实时压缩.html返回。
已确认Nginx编译时包含所需模块:--with-http_gunzip_module --with-http_gzip_static_module
当前核心HTTP配置:
http { gzip on; gzip_static on; gunzip on; }
当前Server块配置:
server { listen 0.0.0.0:443 ssl http2; server_name example.com; root /home/example/www.example.com/current/public; access_log /home/example/log/access.log; include /etc/nginx/bots.d/ddos.conf; include /etc/nginx/bots.d/blockbots.conf; ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; fastcgi_param HTTPS on; fastcgi_param SSL_PROTOCOL $ssl_protocol; fastcgi_param SSL_CIPHER $ssl_cipher; fastcgi_param SSL_SESSION_ID $ssl_session_id; fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify; passenger_enabled on; location ~* ^(.+)\.(png|jpe?g)$ { set $base $1; set $avif_uri $base$avif_suffix; # image.avif set $avif_with_orig_uri $base.$2.$avif_suffix; # image.png.avif expires 1y; add_header Cache-Control public; add_header ETag ""; add_header Vary Accept; log_not_found off; try_files $avif_uri $avif_with_orig_uri $uri =404; } location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } }
解决方案
问题根源是Passenger启用后会接管所有请求流程,包括静态文件请求,导致Nginx的gzip_static模块无法优先处理预压缩文件。需添加显式的location块匹配.html文件,强制Nginx先处理这类请求,跳过Passenger的接管。
调整后的Server块配置如下:
server { listen 0.0.0.0:443 ssl http2; server_name example.com; root /home/example/www.example.com/current/public; access_log /home/example/log/access.log; include /etc/nginx/bots.d/ddos.conf; include /etc/nginx/bots.d/blockbots.conf; ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; fastcgi_param HTTPS on; fastcgi_param SSL_PROTOCOL $ssl_protocol; fastcgi_param SSL_CIPHER $ssl_cipher; fastcgi_param SSL_SESSION_ID $ssl_session_id; fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify; # 优先处理HTML文件,启用gzip_static location ~* \.html$ { gzip_static on; expires max; add_header Cache-Control public; add_header Vary Accept-Encoding; } passenger_enabled on; location ~* ^(.+)\.(png|jpe?g)$ { set $base $1; set $avif_uri $base$avif_suffix; # image.avif set $avif_with_orig_uri $base.$2.$avif_suffix; # image.png.avif expires 1y; add_header Cache-Control public; add_header ETag ""; add_header Vary Accept; log_not_found off; try_files $avif_uri $avif_with_orig_uri $uri =404; } location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } }
关键说明
- 添加的
location ~* \.html$块必须放在passenger_enabled on之前,Nginx会按location块顺序匹配请求,优先匹配的块先处理。 - 在该location块中显式启用
gzip_static on,确保Nginx优先查找并返回预压缩的.html.gz文件。 - 添加
Vary Accept-Encoding头,帮助缓存服务器正确区分不同编码的请求。 - 保留
passenger_enabled on,确保Rails动态请求仍由Passenger处理。
内容的提问来源于stack exchange,提问作者Mark Robinson
相关产品推荐
相关产品推荐

