Laravel 12 → Namecheap Shared Hosting (Stella Plan)
Before deploying, ensure the following are available:
Namecheap shared hosting does NOT support running npm or node on the server. You must build all Vite/Tailwind assets locally before uploading.
Run these commands in your project root on your local machine:
composer install --optimize-autoloader --no-dev
npm install
npm run build
This generates compiled assets in the public/build/ directory.
Ensure public/build/manifest.json exists and public/build/assets/ contains your compiled CSS & JS files.
youraccount_songlyricsyouraccount_slguser with a strong password.Namecheap prefixes database and user names with your cPanel username (e.g., cpanelusr_songlyrics). Note the full names for your .env file.
Create/edit your .env file with production values:
APP_NAME="Song Lyrics Generator"
APP_ENV=production
APP_KEY=base64:YJdq5RoV7iCfxxdWzjZ2LexparFxBB6I1yvu5B1GhiE=
APP_DEBUG=false
APP_URL=https://yourdomain.com
LOG_CHANNEL=stack
LOG_LEVEL=error
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=cpanelusr_songlyrics
DB_USERNAME=cpanelusr_slguser
DB_PASSWORD=your_strong_password_here
GROQ_API_KEY=your_groq_api_key_here
SESSION_DRIVER=database
CACHE_STORE=database
QUEUE_CONNECTION=database
FILESYSTEM_DISK=local
MAIL_MAILER=smtp
MAIL_HOST=mail.yourdomain.com
MAIL_PORT=465
MAIL_USERNAME=noreply@yourdomain.com
MAIL_PASSWORD=your_email_password
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS="noreply@yourdomain.com"
MAIL_FROM_NAME="Song Lyrics Generator"
Critical: Set APP_DEBUG=false and APP_ENV=production. Leaving debug mode on exposes sensitive information (API keys, DB credentials) to the public.
Generate a new APP_KEY for production: run php artisan key:generate locally, then copy the key to your production .env.
You have two options: FTP (FileZilla) or cPanel File Manager.
Upload the entire project except the following:
# DO NOT upload these:
node_modules/
.git/
tests/
.env.example
.phpunit.result.cache
.editorconfig
Upload everything to a folder outside the public web root:
/home/youraccount/songlyrics/
Do NOT upload the entire project into public_html.
/home/youraccount/.songlyrics.After uploading, your server structure should look like this:
The web server must serve files from Laravel's public/ directory. On shared hosting, you have two approaches:
/home/youraccount/songlyrics/public/ into /home/youraccount/public_html/./home/youraccount/public_html/index.php to update the paths:<?php
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
// Determine if the application is in maintenance mode...
if (file_exists($maintenance = __DIR__.'/../songlyrics/storage/framework/maintenance.php')) {
require $maintenance;
}
// Register the Composer autoloader...
require __DIR__.'/../songlyrics/vendor/autoload.php';
// Bootstrap Laravel and handle the request...
(require_once __DIR__.'/../songlyrics/bootstrap/app.php')
->handleRequest(Request::capture());
# SSH into server
ssh youraccount@yourserver
# Backup and remove default public_html
mv public_html public_html_backup
# Create symlink
ln -s /home/youraccount/songlyrics/public /home/youraccount/public_html
Option A is recommended because some Namecheap shared hosting configurations do not follow symlinks. If Option B doesn't work, fall back to Option A.
Via SSH or cPanel File Manager, set the correct permissions:
# SSH into your server, then:
cd /home/youraccount/songlyrics
# Storage and cache must be writable
chmod -R 775 storage
chmod -R 775 bootstrap/cache
# Ensure artisan is executable
chmod +x artisan
Or via cPanel File Manager: right-click the storage and bootstrap/cache folders → Change Permissions → set to 775 recursively.
Connect via SSH and run these commands:
cd /home/youraccount/songlyrics
# Set PHP version (Namecheap may have multiple)
# Use the full path to PHP 8.2+
/usr/local/bin/ea-php82 artisan migrate --force
If the php command defaults to an older version, find the correct binary with: ls /usr/local/bin/ea-php* and use the 8.2+ version explicitly.
/usr/local/bin/ea-php82 artisan storage:link
# Cache routes, config, and views
/usr/local/bin/ea-php82 artisan config:cache
/usr/local/bin/ea-php82 artisan route:cache
/usr/local/bin/ea-php82 artisan view:cache
If you ever update the .env file, you MUST run php artisan config:cache again for the changes to take effect.
Add to the top of public_html/.htaccess:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Ensure your .env has the correct URL:
APP_URL=https://yourdomain.com
Then re-cache config: php artisan config:cache
If your app uses the Laravel task scheduler or queued jobs:
* * * * *):/usr/local/bin/ea-php82 /home/youraccount/songlyrics/artisan schedule:run >> /dev/null 2>&1
Shared hosting doesn't support persistent queue workers. Use the sync driver or configure the scheduler to process jobs:
# In .env, change to sync if queue worker is not needed:
QUEUE_CONNECTION=sync
If you need background queue processing on shared hosting, set up a cron to run queue:work --stop-when-empty every minute instead.
APP_ENV=production and APP_DEBUG=false are setAPP_KEY generated for productionGROQ_API_KEY is set with a valid keystorage/ and bootstrap/cache/ are writable (775)public/build/ contains compiled Vite assetsstorage:link has been createdhttps://yourdomain.com.env file is NOT accessible via browserstorage/logs/laravel.log for the detailed error.storage/ and bootstrap/cache/ permissions are 775.php artisan config:clear then php artisan config:cache.mod_rewrite is enabled (it is by default on Namecheap)..htaccess exists in public_html/.AllowOverride All is set (default on Namecheap).public/build/manifest.json exists.npm run build locally before uploading.APP_URL in .env is correct.GROQ_API_KEY is set in .env..env, run php artisan config:cache.storage/logs/laravel.log for API error details./usr/local/bin/ea-php82 /home/youraccount/songlyrics/artisan clear-compiled
cd /home/youraccount/songlyrics && /usr/local/bin/ea-php82 $(which composer) dump-autoload --optimize
mbstring, openssl, pdo_mysql, tokenizer, xml, ctype, json, bcmath, fileinfo, curl.