Nginx - статический файл, содержащий путаницу с корнем и псевдонимом

473

Мне нужно обслуживать мое приложение через сервер приложений по адресу 8080и статические файлы из каталога, не касаясь сервера приложений. Конфиг nginx у меня есть что-то вроде этого ...

    # app server on port 8080
    # nginx listens on port 8123
    server {
            listen          8123;
            access_log      off;

            location /static/ {
                    # root /var/www/app/static/;
                    alias /var/www/app/static/;
                    autoindex off;
            }


            location / {
                    proxy_pass              http://127.0.0.1:8080;
                    proxy_set_header        Host             $host;
                    proxy_set_header        X-Real-IP        $remote_addr;
                    proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
            }
    }

Теперь с этим конфигом все работает нормально. Обратите внимание, что rootдиректива закомментирована.

Если я активирую rootи деактивирую alias- он перестает работать. Однако, когда я удаляю трейлинг /static/из, rootон снова начинает работать.

Может кто-нибудь объяснить, что происходит. Также , пожалуйста , объясните ясно и пространно , каковы различия между rootи alias, и их цель.

treecoder
источник

Ответы:

1074

Я нашел ответы на мои заблуждения.

Существует очень важное различие между rootи в aliasдирективах. Эта разница существует в способе обработки пути, указанного в rootили alias.

В случае rootдирективы полный путь добавляется к корню, включая часть местоположения , тогда как в случае aliasдирективы к псевдониму добавляется только часть пути, НЕ включающая часть местоположения .

Проиллюстрировать:

Допустим, у нас есть конфиг

location /static/ {
    root /var/www/app/static/;
    autoindex off;
}

В этом случае последний путь, который получит Nginx, будет

/var/www/app/static/static

Это вернется, 404так как нет static/внутриstatic/

Это связано с тем, что часть местоположения добавляется к пути, указанному в root. Следовательно, с root, правильный путь

location /static/ {
    root /var/www/app/;
    autoindex off;
}

С другой стороны, с alias, часть местоположения отбрасывается . Так что за конфиг

location /static/ {
    alias /var/www/app/static/;
    autoindex off;           ↑
}                            |
                             pay attention to this trailing slash

окончательный путь будет правильно сформирован как

/var/www/app/static

Случай конечной косой черты для aliasдирективы

Не существует четких указаний о том, является ли обязательная косая черта в документации Nginx , но обычное наблюдение людей здесь и в других местах, похоже, указывает на то, что это так.

Еще несколько мест обсуждали это, хотя и не окончательно.

/server/376162/how-can-i-create-a-location-in-nginx-that-works-with-and-without-a-trailing-slas

/server/375602/why-is-my-nginx-alias-not-working

treecoder
источник
97
Конечная косая черта на пути псевдонима имеет важное значение!
мафроз
2
Это все замечательно (это помогло мне исправить мои проблемы с конфигурацией), но мне интересно, какие настройки ведения журнала могли бы использовать люди для диагностики подобных проблем? Например, все, что будет печататься в журналах, например, «полученный запрос для [...], соответствующий блоку конфигурации« location [...] », поиск в каталоге [...]» »
Pistos
2
@Pistos: положить log_format scripts '$document_root | $uri | > $request';в httpраздел и access_log /var/log/nginx/scripts.log scripts;в serverраздел конфигурации nginx ..
helvete
Спасибо! Действительно, косая черта необходима для псевдонима, в противном случае я получил nginx: [emerg] invalid number of arguments in "alias" directive, и сервер перестал работать во время перезапуска.
FotisK
@mafrosis Почему это важно?
Брюс Сан
104

как сказать @treecoder

В случае rootдирективы полный путь добавляется к корню, включая часть местоположения, тогда как в случае aliasдирективы к псевдониму добавляется только часть пути, НЕ включающая часть местоположения.

Одна картинка стоит тысячи слов

для root:

введите описание изображения здесь

для alias:

введите описание изображения здесь

liuzhijun
источник
11
Должна ли первая стрелка на втором изображении быть "+"?
17
35

В вашем случае вы можете использовать rootдирективу, потому что $uriчасть locationдирективы такая же, как и в последней rootчасти директивы.

Документация Nginx также советует:
когда location соответствует последней части значения директивы:

location /images/ {
    alias /data/w3/images/;
}

вместо этого лучше использовать корневую директиву:

location /images/ {
    root /data/w3;
}

и rootдиректива добавит $uriк пути.

antonbormotov
источник
2
Почему лучше? Документы тоже не говорят.
HostedMetrics.com
Преимущество, которое я вижу, состоит в том, чтобы избежать дублирования $ uri, / images в данном примере при использовании псевдонима
antonbormotov
21

Просто быстрое дополнение к очень полезному ответу @ good_computer, я хотел заменить корень URL-адреса на папку, но только если он соответствовал подпапке, содержащей статические файлы (которую я хотел сохранить как часть пути).

Например, если запрошенный файл находится в /app/jsили /app/css, посмотрите в /app/location/public/[that folder].

Я получил это, чтобы работать с помощью регулярных выражений.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
meloncholy
источник
2
Спасибо за этот ответ. Я знаю, что это 3 года спустя, но кто-нибудь может объяснить, есть ли компромисс между производительностью и / или безопасностью между использованием псевдонима и root?
Мина
1
@Mina Лучше использовать root, если можете. (Есть комментарий в документации wiki.nginx.org/HttpCoreModule#alias )
Мэтью Уилкоксон
Это именно то, что я пришел сюда 👍👏
AlienFromouterspace
6

aliasиспользуется для замены пути части местоположения (LPP) в пути запроса, в то время rootкак используется для добавления к пути запроса.

Это два способа сопоставить путь запроса с окончательным путем к файлу.

aliasможет использоваться только в блоке местоположения, и он переопределит внешний root.

aliasи rootне может использоваться в блоке местоположения вместе.

Яо Чжао
источник
3
server {
    server_name xyz.com;
    root /home/ubuntu/project_folder/;

    client_max_body_size 10M;
    access_log  /var/log/nginx/project.access.log;
    error_log  /var/log/nginx/project.error.log;

    location /static {
        index index.html;
    }

    location /media {
        alias /home/ubuntu/project/media/;
    }
}

Блок сервера, чтобы жить статической страницей на nginx.

Tapish
источник
2

Другими словами, соблюдая это кратко: в случае root, указанный аргумент location является частью пути и URI файловой системы . С другой стороны - для aliasдирективы аргумент оператора location является частью только URI

Таким образом, aliasэто другое имя, которое отображает определенный URI на определенный путь в файловой системе, тогда как rootдобавляет аргумент location к корневому пути, указанному в качестве аргумента rootдирективы.

Twissell
источник