Drupal + nginx + apache (mod_php) отдаем "статику" через nginx
В сети масса статей, подробно расписывающих почему для отдачи статики с сервера нужно использовать nginx, а не apache. Это и быстрее и менее нагружает сервер и т.д. Поэтому я на этом сейчас останавливаться не буду.
Проблема с CMS Drupal (именно с ней я больше всего работаю - она очень удобна и практична) состоит в том, что файлы стилей (css), javascript (js), а в при применении некоторых модулей (например colorbox, ubercart) и изображения (разных стилей - превью и т.д.) генерируются динамически. Т.е. система физически записывает файл на диск (формирует объединенный css или js, обрабатывает исходное изображение) только после первого к нему обращения. При чем после сброса кэша файлы css и js меняют свое имя и создается заново. Именно поэтому самый распространенный в сети пример конфига nginx для отдачи статики не подходит:
server {
listen 80;
server_name mydomain;
sendfile on;
keepalive_timeout 20;
location / {
proxy_pass http://127.0.0.1:8181;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location ~* ^.+.(jpg|jpeg|gif|png|ico|cur|pdf|doc|txt|xls|rar|exe|zip|mp3|avi|css|js|cdr)$ {
root /usr/home/www/mydomain.folder/data/;
expires 30d;
}
}
Но при таком варианте конфига (как я уже писал выше) при сбросе кэша, или при загрузке изображения через colorbox или ubercart файл автоматически не формируется и nginx выдает вместо файла ошибку 404 Not Found. Соответственно эту самую ошибку и нужно обработать и, если она возникает, сделать такой же запрос на apache и, соответственно, Drupal для формирования нужного файла и, в последующем, отдачи его посредством nginx. Для этого немного видоизменяем конфиг, делаем обработку ошибки 404 и перенаправляем запрос. Для этого добавляем в блок отдачи статики строку "error_page 404 = @fallback;" и описываем этот самый "@fallback" совершенно аналогично "location /":
server {
listen 80;
server_name mydomain;
sendfile on;
keepalive_timeout 20;
location / {
proxy_pass http://127.0.0.1:8181;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location ~* ^.+.(png|jpg|gif|jpeg|ico|cur|pdf|doc|txt|xls|rar|exe|zip|mp3|avi|djvu|xslx|css|js)$ {
root /usr/home/www/mydomain.folder/data/ ;
expires 30d;
error_page 404 = @fallback;
}
location @fallback {
proxy_pass http://127.0.0.1:8181$request_uri;
port_in_redirect on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
Получившийся конфиг позволяет отдавать картинки, css и js через nginx и при этом не боятся получить ошибку 404 Not Found при сбросе кэша и/или первичном формировании картинки.