Laravel runs well on cPanel hosting with LiteSpeed and a current PHP version. The key point is that only Laravel's public folder should be reachable from the web; everything else, including .env with your secrets, must stay outside the document root. This guide walks through a clean deployment.
Before you start
- SSH or Terminal access for Composer and Artisan commands.
- A PHP version supported by your Laravel release, selected in MultiPHP Manager, with extensions such as
mbstring,openssl,pdo_mysql,tokenizer,xml,ctype,fileinfoandbcmathenabled. - A MySQL database and user: create them.
Put the code outside public_html
- With Git: clone into
~/apps/myappusing Git Version Control orgit clonein Terminal. - Without Git: upload a ZIP of the project (without
vendorandnode_modules) to~/apps/myappand extract it in File Manager.
Point the domain to the public folder
- Open cPanel → Domains → Domains.
- For an addon domain or subdomain, click Manage and set the Document Root to
apps/myapp/public, then save. - For the primary domain, whose root is fixed to
public_html, either host the app on a subdomain, or replacepublic_htmlwith a symlink in Terminal after backing it up:mv ~/public_html ~/public_html.bak && ln -s ~/apps/myapp/public ~/public_html
Install dependencies and configure
cd ~/apps/myappcomposer install --no-dev --optimize-autoloadercp .env.example .env && php artisan key:generateEdit .env in File Manager:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://app.example.com
DB_HOST=localhost
DB_DATABASE=cpuser_app
DB_USERNAME=cpuser_appuser
DB_PASSWORD=your-passwordThen run:
php artisan migrate --forcephp artisan storage:linkphp artisan config:cache && php artisan route:cache && php artisan view:cacheTip: If php in Terminal is a different version than the website, call the right binary, e.g. /opt/cpanel/ea-php83/root/usr/bin/php artisan migrate.
Build front-end assets
Run npm run build on your computer and upload the public/build folder. Building with Node on shared hosting uses a lot of memory and can hit resource limits.
Scheduler and queues
- Add a cron job every minute:
cd /home/cpuser/apps/myapp && php artisan schedule:run >> /dev/null 2>&1 - Long-running
queue:workprocesses are not suitable for shared hosting. UseQUEUE_CONNECTION=databaseand process jobs from the scheduler withqueue:work --stop-when-empty.
Permissions
storage and bootstrap/cache must be writable by your user; 755 folders and 644 files are enough because PHP runs as your account. Never use 777.
Troubleshooting
- 500 error, blank page: read
storage/logs/laravel.logand the error log. MissingAPP_KEYand cached config are common causes; runphp artisan config:clear. - 404 on every route except /: the document root is not the
publicfolder, or its.htaccessis missing. - Composer out of memory: run
composer installlocally and uploadvendor, or contact support.
