Как конвертировать .htaccess в nginx: пошаговое руководство

    При переходе с Apache на nginx разработчики часто сталкиваются с необходимостью переносить правила перезаписи URL из файла .htaccess в конфигурацию nginx. Прямые онлайн-конвертеры не всегда дают рабочий результат из-за различий в синтаксисе и логике работы серверов. В этой статье мы разберём, как вручную преобразовать типовые директивы RewriteCond и RewriteRule в эквивалентные инструкции nginx.

    Понимание задачи: что делает исходный код

    Исходный блок из .htaccess проверяет, является ли запрошенный файл реально существующим, и если нет - перенаправляет все запросы на index.php с параметром path. Директивы RewriteCond исключают:

    • !-f - если запрошенный файл не существует;
    • !-d - если запрошенная директория не существует;
    • !-s - если файл не имеет ненулевого размера (не пустой);
    • !-l - если файл не является символической ссылкой.

    В nginx аналогичная логика реализуется через директиву try_files.

    Правильное решение для nginx

    Наиболее грамотный способ конвертации - использовать блок location / с директивой try_files. Вот рабочий код:

    location / {
        try_files $uri $uri/ /index.php?path=$uri&$args;
    }

    Эта директива последовательно проверяет:

    • $uri - существует ли файл с таким именем;
    • $uri/ - существует ли директория;
    • /index.php?path=$uri&$args - если ни один из предыдущих вариантов не сработал, запрос передаётся index.php с параметрами пути и оригинальными аргументами.

    Почему онлайн-конвертеры ошибаются

    Многие автоматические инструменты пытаются буквально перевести каждую строку .htaccess, создавая избыточные блоки if в nginx. Например, они могут генерировать:

    if (!-f $request_filename) { ... }

    Такие конструкции работают медленнее и могут приводить к неожиданным ошибкам. Использование try_files - это идиоматичный и производительный подход для nginx.

    Дополнительные настройки: обработка PHP и кэширование

    Чтобы конфигурация была полностью работоспособной, добавьте блок для обработки PHP-файлов через FastCGI:

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    }

    Также рекомендуется настроить кэширование статических файлов для ускорения загрузки сайта:

    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control \"public, no-transform\";
    }

    Проверка конфигурации

    После внесения изменений обязательно проверьте синтаксис командой:

    nginx -t

    Если тест пройден успешно, перезагрузите nginx:

    systemctl reload nginx

    Теперь все запросы, не ведущие к реальным файлам или папкам, будут корректно направляться в index.php, как и в исходной конфигурации Apache.

    Часто задаваемые вопросы