sudo pacman -S nginx
# Главный конфиг:
/etc/nginx/nginx.conf
# Виртуальные хосты (обычно создают вручную):
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
Блок server {...} переносим из /etc/nginx/nginx.conf в /etc/nginx/sites-available/mysitename. А в /etc/nginx.conf добавляем в самом низу блока http:
# include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
Дефолтный конфиг:
worker_processes 1;
include modules.d/*.conf;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
Структура моего проекта примерно такая:
public/
├── main/
│ ├── subpage
│ │ ├── index.html
│ │ └── page1.html
│ ├── index.html
│ ├── page1.html
│ └── page2.html
└── assets/
├── css/
├── js/
└── images/
Поэтому я подправлю конфиг:
worker_processes 1;
include modules.d/*.conf;
events {
worker_connections 1024;
}
http {
# Добавляем размеры хеш-таблицы MIME-типов:
types_hash_max_size 2048;
types_hash_bucket_size 128;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
# Выносим root на уровень папки public:
root /home/mark/projects/node/my.mclang.ru/public;
location / {
try_files /main$uri /main$uri/index.html =404;
}
location /assets/ {
try_files $uri =404;
}
}
}
Зачем мы добавили вот эти строки:
types_hash_max_size 2048;
types_hash_bucket_size 128;
Если их не добавить, то при запуске nginx, он ругается: warn: could not build optimal types_hash. You should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size. Nginx недоволен размером хеш-таблицы MIME-типов. В конфиге есть строка include mime.types. Файл mime.types содержит список расширений. Nginx строит из этого хеш-таблицу для быстрого определения Content-Type. Если список большой, то стандартные размеры (types_hash_max_size 1024; types_hash_bucket_size 64) могут оказаться малы.
Предупреждение может появляться, когда есть расширенный mime.types или добавлены кастомные типы.
Подробно разберём вот эту строку:
try_files /main$uri /main$uri/index.html =404;
Если я хочу ещё и проверять наличие файла index.htm, то тогда подправим её таким образом:
try_files /main$uri /main$uri/index.html /main$uri/index.htm =404;
/main$uri – здесь мы проверяем точное соответствие URI файлу. Если мы введём в строку браузера http://localhost/arch/page1.html, то в нашем случае nginx станет искать /home/mark/projects/node/my.mclang.ru/public/main/arch/page.html. Если такой файл существует, то nginx вернёт его браузеру. Если такого файла нет, то переходим к следующему fallback-варианту.
/main$uri/index.html – срабатывает в том случае, если файл из предыдущего примера не найден. Если он не найден, то возвращаем /home/mark/projects/node/my.mclang.ru/public/main/arch/index.html. Если мы вводим в строку браузера http://localhost/arch, то сначала мы ищем конкретный файл, чтобы его вернуть, т.е. /home/.../main/arch, но arch – это директория, а не файл → Не подходит, как конечный файл – не можем его вернуть. А значи переходим к следующему аргументу try_files, а именно: /main$uri/index.html. То есть, возвращаем из этой найденной директории файл index.html. Если же и он не найден, то переходим к следующему аргументу: пробуем вернуть из этой же директории файл index.htm. А если и он не найден, то возвращаем страничку с ошибкой "404".
Если я введу в строку браузера http://localhost/arch/ (то есть добавлю "/"), то логика в принципе будет та же. Единственная разница в том, что без слэша nginx сначала ищет файл arch, а со слэшем – он сразу пытается вернуть папку /arch/. А так как папку вернуть нельзя, он переходит к следующему аргументу, т.е. пытается вернуть /main/arch/ + /index.html. То есть: /main/arch//index.html – с двумя слэшами. Nginx конечно убирает лишний слэш и возвращает /home/.../main/public/arch/index.html. И так далее.
В дефолтном файле записано вот так (ЗАПИСЬ #1):
...
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
...
}
Можно записать вот так (ЗАПИСЬ #2):
server {
listen 80;
server_name localhost;
# Указываем root-папку:
root /home/mark/projects/node/my.mclang.ru/public;
location / {
try_files $uri $uri/ =404;
index index.html index.htm;
}
...
}
В этом случае файлы index.html и index.htm будут искаться в текущей директории и во всех вложенных.
Но если мы хотим указать, чтобы файлы искались не в текущем .../public, а во вложенном .../public/main, то тогда придётся записать вот таким образом (ЗАПИСЬ #3):
# Это та же запись, что и в предыдущем примере,
# но здесь главный index.html находится в папке .../public/main/
server {
listen 80;
server_name localhost;
# Указываем root-папку:
root /home/mark/projects/node/my.mclang.ru/public;
location / {
try_files /main$uri /main$uri/index.html /main$uri/index.htm;
}
...
}
Вопрос возникает, когда мы смотрим на ЗАПИСЬ2 и ЗАПИСЬ3 в секцию location. Строка try_files $uri $uri/ =404; ведёт себя иначе.
Важно!!! try_files ведёт себя по-разному в ЗАПИСИ2 и в ЗАПИСИ3. Если $uri у нас совпадает с оригинальным URI, то мы получаем одно поведение, а если мы изменяем $uri в try_files, то получаем другое поведение.
В ЗАПИСИ2 если мы не нашли точное совпадение $uri, то мы сначала ищем index.html и index.htm в текущей папке. Если их нет, то возвращаем папку $uri/. И в этой папке ищутся файлы index.html и index.htm, которые указаны в index. Происходит inner redirect – мы как бы оказываемся внутри папки $uri/. Если там есть вложенная папка и мы её запросим, то происходит как бы переход в следующую поддиректорию (inner redirect) и файлы, указанные в index, ищутся там.
В ЗАПИСИ3 inner redirect не работает, потому что там не $uri, а /main$uri, то есть $uri не соответствует оригинальному URI. $uri изменённый и логика поведения другая: здесь index index.html index.htm работать не будет. Придётся явно указывать файл, который мы хотим вернуть, если не найдено точного совпадения.
Структура конфигурационных файлов:
/etc/nginx/
├── nginx.conf
├── modules.d/
├── conf.d/
│ └── custom.conf
├── sites-available/
│ ├── site1.conf
│ └── site2.conf
├── sites-enabled/
├── site1.conf -> ../sites-available/site1.conf
└── site2.conf -> ../sites-available/site2.conf
Мой текущий конфиг:
server {
listen 80;
server_name localhost;
root /home/mark/projects/node/my.mclang.ru/public;
location / {
try_files /main$uri /main$uri/index.html =404;
}
location /assets/ {
try_files $uri =404;
}
}
Можно добавить alias и тогда будет так:
server {
listen 80;
server_name localhost;
root /home/mark/projects/node/my.mclang.ru/public;
location / {
alias /home/mark/projects/node/my.mclang.ru/public/main/;
try_files $uri $uri/ =404;
}
location /assets/ {
try_files $uri =404;
}
}