# Проблема
Популярнейшая ошибка начинающих разработчиков - размещение проекта на виртуальном хостинге и как следствие загрузка всего исходного кода в общедоступный каталог public_html или иной, как в случае с простыми CMS, например, WordPress. С Laravel такой подход не работает и вместо сайта отображается, или каталог с файлами, или 403 Forbidden, или сообщение о циклической переадресации, или не работают ссылки на стили, скрипты и обычные файлы.
В попытках запустить проект, разработчик совершает серьёзную ошибку и пытается перенаправить запросы в public/index.php из корня проекта.
Во-первых, это нарушение безопасности, файл .env доступен в web,
как и всё остальное (composer.json, любые приватные файлы на диске, например, дамп базы данных).
Во-вторых, переадресация запросов через .htaccess
это дополнительная нагрузка и увеличение TTFB.
В-третьих, это приводит к другим разнообразным проблемам связанных с некорректной "переадресацией" запроса.
Ни в коем случае не проксируй запросы через htaccess, только содержимое public должно быть доступно в web.
# Проблема хостингов
Шаред-хостинги не подходят под фреймворки, которые более требовательны к окружению, чем CMS. Даже с наличием ssh-доступа и более-менее функционального cli, проблемы не ограничиваются корневой директорией:
- Ограниченные ресурсы железа.
- Могут быть недоступны какие-либо расширения php.
- Может не быть требуемой версии php для web или для cli.
- Ограниченные возможности настройки php.ini или баз данных.
- Сложности с запуском демона для очередей.
- Отсутствует node или установлена устаревшая версия.
- Нет возможности использовать Websockets, Supervisor, Octane, Docker, Redis, Varnish, Meilisearch...
Данный список можно продолжать очень долго, всё зависит от технологий использующихся в проекте. Если ко всему этому и нет нормальной консоли с php cli и git, то это вообще безумие...
В примерах ниже будет использоваться public_html как директория web-сервера. Имя директории варьируется от провайдера и в твоём случае может быть иной, например, www, docs, html, htdocs, domains и т.д.
# Решение 1: Взять VPS
Отказаться от шаред-хостинга и взять по той же цене обычный VPS, в котором можно свободно настроить среду. Это самый адекватный и правильный вариант. Для настройки сервера тебе понадобятся базовые знания в linux, которые должны быть у каждого backend разработчика. Если у тебя VPS или решил на него перейти, то смотри второй пункт «Как настроить DocumentRoot».
# Решение 2: Настроить DocumentRoot
Настроить web-сервер и изменить document_root так, чтобы он смотрел в public
1# Nginx2server {3 root /srv/example.com/public;4}
1# Apache2<VirtualHost>3 DocumentRoot /srv/example.com/public4</VirtualHost>
Некоторые современные хостинги позволяют настраивать корневую директорию, уточни у тех. поддержки и если такой возможности нет, то читай дальше...
# Решение 3: Сделать SymLink
Создать
символическую ссылку
на public
Сделать это можно через консоль или в файловом менеджере (зависит от провайдера)
- Приложение загружается в любую доступную директорию кроме public_html или на один уровень выше, так чтобы public_html хостинга и public фреймворка были в одной директории. Расположение проекта может быть любым, главное указать правильный путь к директории public в символической ссылке.
- Удаляется директория хостинга public_html
-
Создаётся симлинк public_html на public
любым доступным способом:
1ln -s /path_to_project/public /path_to_old/public_html
Обрати внимание, что пути указаны абсолютно.
В результате мы "восстанавливаем" public_html, но это уже не директория,
а ссылка на public
Поэтому настройки web-сервера остаются прежними,
а запросы приходят в public/index.php
Это простой вариант, но не все хостеры дают возможность создавать символические ссылки.
Также данный вариант не рекомендуется при использовании OPCache, чтобы обезопасить развертывание приложений из-за realpath-кэша, подробнее читай в статье "Обзор расширения OPCache" .
# Решение 4: Переименовать public
Переименовать public в public_html
Для этого переименовываем саму директорию и переопределяем путь в App\Providers\AppServiceProvider
1public function register()2{3 $this->app->bind('path.public', function() {4 return base_path().'/public_html';5 });6}
Обрати внимание, что для локальной разработки директорию придётся переименовать всем кто работает с проектом.
Если используется Laravel 8.x или более старая версия, то для работы php artisan serve необходимо изменить путь в server.php .
Если используется Mix, то потребуется использовать
mix.setPublicPath()
Если используется Vite, то необходимо изменить
build_path
Также не забудь внести изменения в .gitignore