Понимание блока местоположения nginx и использование пассажира с именованными блоками местоположения

У меня есть пара вопросов относительно моей конфигурации nginx, поскольку она относится к обслуживанию файлов webp, а также к использованию именованных местоположений с try_files.

Текущая конфигурация:

server {
    listen 80;
    server_name  assets.manager manager;
    passenger_app_env production;
    passenger_ruby /home/web-server/.rvm/gems/ruby-2.2.1@manager/wrappers/ruby;
    passenger_enabled on;

    error_log  /home/web-server/web-applications/manager/current/log/nginx-error.log;
    root       /home/web-server/web-applications/manager/current/public;

    satisfy any;
    allow 127.0.0.1;
    allow 192.168.0.0/24;
    deny all;

    location ~ ^/assets/ {
        gzip_static on;
        expires     max;
        add_header  Cache-Control public;
        add_header  Last-Modified "";
        add_header  ETag "";
    }

    location ~* .+\.(?:png|jpe?g|gif)$ {
        if ($webp_suffix != "") {
            add_header Vary Accept;
        }
        try_files $uri$webp_suffix $uri =404;
    }
}

В настоящее время nginx не обслуживает файлы webp. Если бы я поместил add_header X-Webp-Uri "$uri$webp_suffix"; в первый блок location, заголовок был бы добавлен. Если бы я поместил это во второй блок png/jpeg, соответствующий location, заголовок не был бы установлен. Насколько я понимаю, блоки местоположения регулярных выражений являются последовательными (т. Е. Сопоставление не прекращается при первом совпадении).

1) Я хочу обслуживать изображения webp, если они есть (моя попытка сделать это — 2-й блок location). Поможет ли в этом случае наличие вложенного блока location? Я хочу установить gzip_static, expires и т. д. для ВСЕХ файлов в /assets/, но я хочу обслуживать версию webp только в том случае, если они существуют для определенных расширений файлов в /assets/.

2) В другой теме я хочу обслуживать статические файлы .html, если они есть. Для этого (после поиска руководств в Интернете) мне нужна комбинация try_files и именованного блока местоположения, который указывает на вышестоящее приложение (Rails). Однако я не могу понять, как объявить восходящий блок, если я использую Passenger (установлен с использованием passenger-install-nginx-module). Единственные конфигурации, которые я могу найти для установки Passenger/Nginx, — это использовать passenger_enabled on;


РЕДАКТИРОВАТЬ: я нашел образец конфигурации; вот пример (это игнорирует проблему № 1):

server {
    listen 80;
    server_name  assets.staging.pos staging.pos;
    passenger_app_env staging;
    passenger_ruby /home/vagrant/.rvm/gems/ruby-2.2.1@pos/wrappers/ruby;
    passenger_enabled on;

    error_log  /home/vagrant/rails/staging.pos/log/nginx-error.log;
    root       /home/vagrant/rails/staging.pos/public;

    try_files $uri /cache/$uri /cache/$uri.html @app;

    location @app {
        proxy_set_header X-Forwarded-Proto http;
    }

    location ~* ^/images/.+\.(png|jpe?g)$ {
      if ($webp_suffix != "") {
        add_header Vary Accept;
      }

      try_files $uri$webp_suffix $uri =404;
    }
}

РЕДАКТИРОВАТЬ 2: я обнаружил, что nginx полностью стирает все инструкции за пределами блока if!

В результате будет установлен только заголовок Vary Accept:

server {
    location ~* ^/images/.+\.(png|jpe?g)$ {
        add_header X-Whatever "Yo";
        if ($webp_suffix != "") {
          add_header Vary Accept;
        }
    }
}

Это приведет к установке обоих заголовков:

server {
    location ~* ^/images/.+\.(png|jpe?g)$ {
        if ($webp_suffix != "") {
          add_header Vary Accept;
          add_header X-Whatever "Yo";
        }
    }
}

РЕДАКТИРОВАТЬ 3: Так что теперь это еще больше сбивает с толку. Это похоже на то, что любой предыдущий add_header, который не находится в последнем блоке кода (расположение или оператор if), полностью игнорируется. т. е. при следующем устанавливается только заголовок X-Whatever:

location ~ ^/assets/ {
    gzip_static on;
    expires     max;
    add_header  Cache-Control public; # Ignored?!
    add_header  Last-Modified ""; # Ignored?!
    add_header  ETag ""; # Ignored?!

    location ~* ^/assets/.+\.(?:png|gif|jpe?g)$ {
        add_header X-Something "$uri$webp_suffix"; # Not ignored!
    }
}

person SnakeWasTheNameTheyGaveMe    schedule 11.10.2015    source источник


Ответы (1)


Мне пришлось удалить условие заголовка Vary Accept и просто всегда применять его. Я не знаю, хорошо это или плохо, но у меня нет другого выбора, учитывая, что он просто удаляет все остальные заголовки, которые я применил! Мне также пришлось переместить блок местоположения webp над блоком ресурсов и дублировать код, что отстой.

Рабочая конфигурация:

server {
    listen 80;
    server_name  assets.staging.pos staging.pos;
    passenger_app_env staging;
    passenger_ruby /home/vagrant/.rvm/gems/ruby-2.2.1@pos/wrappers/ruby;
    passenger_enabled on;

    error_log  /home/vagrant/rails/staging.pos/log/nginx-error.log;
    root       /home/vagrant/rails/staging.pos/public;

    # Try to return cached responses without hitting the app
    try_files $uri /cache/$uri /cache/$uri.html @app;

    location @app {
        proxy_set_header X-Forwarded-Proto http;
    }

    # Return webp images when possible
    location ~* ^/assets/.+\.(?:png|gif|jpe?g)$ {
        expires     max;
        add_header  Cache-Control public;
        add_header  Vary Accept;
        add_header  Last-Modified "";
        add_header  ETag "";

        try_files $uri$webp_suffix $uri =404;
    }

    # Regular asset headers
    location ~ ^/assets/ {
        gzip_static on;
        expires     max;
        add_header  Cache-Control public;
        add_header  Last-Modified "";
        add_header  ETag "";
    }
}
person SnakeWasTheNameTheyGaveMe    schedule 12.10.2015