Модуль 10

Index, try_files та fallback-логіка

Ось готовий урок, створений спеціально для тебе у стилі Гарвардського курсу CS50. Пристебни паски — ми пірнаємо в глибини конфігурації вебсервера!


🎓 Урок: Index, try_files та Fallback-логіка в Nginx

Всім привіт! Я радий бачити вас на цьому занятті.

Сьогодні ми поговоримо про те, як вебсервер приймає рішення. Коли ви вводите адресу в браузері та натискаєте Enter, сервер (у нашому випадку Nginx) має частку секунди, щоб зрозуміти: "Що саме я маю віддати цьому користувачеві?".

Файл? Картинку? Результат роботи скрипта? Чи, можливо, ввічливо сказати, що такої сторінки не існує?

Сьогодні ми розберемо директиви index та try_files. Це фундамент маршрутизації (роутингу) в Nginx. Без цього ваші Single Page Applications (React, Vue) не працюватимуть, а "красиві посилання" у WordPress залишаться мрією.

Готові? Поїхали!


1. 🔥 Вступ: Проблема та мотивація

Уявіть, що ви приходите у велику бібліотеку. Ви підходите до бібліотекаря і кажете: "Я хочу почитати про 'Історію України'".

Бібліотекар (це наш Nginx) має алгоритм дій: 1. Чи є книга з точною назвою "Історія України"? 2. Якщо ні, чи є розділ (папка) з такою назвою? Якщо так, то яку книгу з цього розділу дати першою? (Вступ? Зміст?) 3. А що, якщо такої книги взагалі немає? Сказати "Іди геть"? Чи запропонувати каталог схожих книг?

У світі вебу це виглядає так: Користувач вводить my-site.com/profile. Але ж стривайте! У вас на диску сервера немає файлу з назвою profile. У вас є лише index.html, який запускає React-додаток, і вже JavaScript малює сторінку профілю.

Риторичне питання: Якщо файлу profile фізично не існує, як змусити Nginx не видавати помилку 404 Not Found, а віддати index.html, але при цьому зберегти адресу /profile в рядку браузера?

Ось тут на сцену виходить магія try_files. Без неї сучасний інтернет просто розсипався б.


2. 🧠 Теоретична база (без нудної академічності)

Давайте розберемо два ключові інструменти, які є у нашого "бібліотекаря".

1. Директива index

Це просто список "улюблених книг" для папки. Якщо запит прийшов на папку (наприклад, /), Nginx дивиться в цю директиву, щоб зрозуміти, який файл відкрити за замовчуванням.

index index.html index.php;

Як це працює: "Якщо користувач просить папку, пошукай там index.html. Якщо його немає — пошукай index.php. Якщо і його немає — тоді вже видавай помилку (або список файлів, якщо дозволено)".

2. Директива try_files (Зірка сьогоднішнього шоу ⭐️)

Це найпотужніша інструкція перевірки існування файлів. Її назва говорить сама за себе: "Спробуй файли...".

Синтаксис виглядає так:

try_files файл1 файл2 файл3 ... фінальний_варіант;

Логіка "під капотом": Nginx перевіряє шляхи зліва направо: 1. Файл1 існує? Так -> Віддай його і закінчи роботу. 2. Ні? Окей, перевіряємо Файл2. 3. Файл2 існує? Так -> Віддай його. 4. Ні? ... і так далі. 5. Нічого не знайдено? Виконуй останній аргумент (це і є наш Fallback).

❗️ Що треба запам'ятати: try_files перевіряє фізичну наявність файлів на диску. Останній аргумент — це рятівне коло. Це те, що станеться, якщо нічого не знайдено.


3. 🧪 Приклади (від простого до реального)

Приклад №1: Класичний сайт (HTML + PHP)

У нас є звичайний сайт. Користувач заходить на example.com/.

server {
    root /var/www/mysite;
    index index.php index.html;
}

❓ Що відбудеться? Nginx загляне в папку /var/www/mysite. Спочатку він шукатиме index.php. Якщо знайде — запустить його. Якщо ні — шукатиме index.html. Це просто, як двері.


Приклад №2: Single Page Application (React/Vue/Angular) — Реальний кейс!

Це найпопулярніша задача. Користувач переходить за посиланням example.com/dashboard/settings. Але папки dashboard на сервері не існує! Це віртуальний маршрут.

Ми хочемо: 1. Якщо такий реальний файл є (наприклад, картинка logo.png) — віддай його. 2. Якщо немає — віддай index.html (щоб React завантажився і сам розібрався з URL).

location / {
    try_files $uri $uri/ /index.html;
}

Давайте розберемо це заклинання: * $uri: "Спробуй знайти файл, який точно відповідає запиту" (наприклад, style.css). * $uri/: "Якщо файлу немає, перевір, може це папка?" (шукає папку з таким іменем). * /index.html: "Якщо ні файлу, ні папки немає — просто віддай index.html".

Чому це круто? Користувач бачить .../settings, але сервер віддає йому оболонку програми, яка вміє цей settings відобразити.


Приклад №3: Картинка-заглушка (Fallback)

Уявіть інтернет-магазин. Ви запитуєте фото товару product123.jpg. Але менеджер забув завантажити фото! Замість потворної помилки 404, ми хочемо показати картинку "default.jpg" (сірий квадрат з камерою).

location /images/ {
    try_files $uri /images/default.png;
}

Результат: Якщо product123.jpg існує — користувач бачить товар. Якщо ні — Nginx тихо підсовує default.png, але (важливо!) URL у браузері залишається старим. Користувач навіть не помітить підміни.


4. 🛠 Практична частина

Час "забруднити руки" кодом. Уявіть, що ви налаштовуєте сервер для стартапу.

Завдання 1: Налаштування пріоритетів У папці сайту лежать два файли: home.html та index.html. Напишіть директиву index так, щоб при вході на сайт відкривався home.html. А якщо його видалять — то index.html.

Завдання 2: "Тимчасово недоступний" Сайт на реконструкції. Налаштуйте try_files так, щоб на будь-який запит користувача (крім картинок) сервер віддавав файл maintenance.html. (Підказка: останній аргумент try_files може вказувати на конкретний файл).

Завдання 3: Виправлення помилки (Debug) Джуніор написав такий конфіг для React-додатка:

location / {
    try_files $uri /index.html;
}

Користувачі скаржаться, що не можуть відкрити вкладені папки, які реально існують (наприклад, mysite.com/docs/). Чому? Що він забув додати в ланцюжок?

Завдання 4: Міні-кейс "Безпека" Ви хочете, щоб користувачі не могли безпосередньо завантажувати .php файли, якщо вони не проходять через головний контролер (Front Controller). Створіть логіку, де будь-який запит, який не знаходить реальний файл, перенаправляється на index.php.

try_files $uri $uri/ /index.php?$args;

Питання: Навіщо тут $args в кінці?


5. 💡 Мислення як у розробника

Як думає досвідчений DevOps або Backend-розробник, коли пише ці рядки?

  1. "Порядок має значення". Новачки часто пхають все підряд в try_files. Професіонал знає: кожна перевірка — це системний виклик до жорсткого диска. Чим менше перевірок, тим швидше працює сайт. Ставте найімовірніші варіанти на початку.

  2. Остерігайтесь "Нескінченних циклів". Типова помилка: nginx location / { try_files $uri /missing.html; } А що, якщо файлу missing.html теж не існує? Nginx спробує знайти його, не знайде, знову спробує виконати останній аргумент... і впаде з помилкою 500 Internal Server Error (Rewrite or internal redirection cycle). Порада: Завжди будьте впевнені, що ваш Fallback-файл (останній аргумент) точно існує.

  3. Іменовані локації (@backend). Замість того, щоб вказувати файл в кінці, профі часто використовують "іменовану локацію". ```nginx try_files $uri $uri/ @proxy_to_app;

    location @proxy_to_app { proxy_pass http://localhost:3000; } ``` Це робить конфіг чистим і читабельним: "Спробуй знайти файл. Не знайшов? Віддай запит на Node.js/Python бекенд".


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку?

  1. index — це всього лише значення за замовчуванням для папок.
  2. try_files — це "шукач", який перебирає варіанти зліва направо.
  3. Останній аргумент у try_files — це ваш план "Б" (Fallback).

Що ви тепер вмієте: ✅ Правильно запускати Single Page Applications (React/Vue) на Nginx. ✅ Створювати заглушки для відсутніх файлів. ✅ Розуміти, чому сервер видає той чи інший файл.

Ви більше не "тикаєте навмання", копіюючи конфіги зі StackOverflow. Ви розумієте логіку потоку даних.

🔜 У наступній серії: Ми навчилися знаходити статичні файли. Але що робити, коли треба передати дані іншому серверу? У наступному уроці ми розберемо Reverse Proxy та proxy_pass. Як змусити Nginx бути "фасадом" для вашого Python або Node.js додатка.

Це був CS50... тобто, ваш курс Nginx. До зустрічі! 💻🚀