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 при сбросе кэша и/или первичном формировании картинки.