Prerequisites & Requirements
Local Requirements
- Completed Laravel application
- Composer installed locally
- Access to project files
- Database export (SQL file)
Hosting Requirements
- cPanel hosting account
- PHP 8.0+ support
- MySQL database access
- File Manager access
This tutorial covers shared hosting deployment. For VPS or dedicated servers, the process may differ slightly.
Deployment Process Overview
Prepare Files
Organize and compress project files
Upload Files
Upload to correct directories
Setup Database
Create and import database
Configure
Update configuration files
Step 1: Prepare Your Laravel Files
Understanding Laravel Directory Structure
Laravel applications have a specific structure. The public folder contains files that should be web-accessible, while everything else should remain private.
Laravel Project Structure:
Create Two Separate Archives
📁 Archive 1: Root Files (excluding public)
- • app/
- • bootstrap/
- • config/
- • database/
- • resources/
- • routes/
- • storage/
- • vendor/
- • .env.example
- • composer.json
- • artisan
📁 Archive 2: Public Folder Contents
- • index.php
- • .htaccess
- • css/ (compiled assets)
- • js/ (compiled assets)
- • images/
- • favicon.ico
- • robots.txt
Never include your .env file in uploads. Always create a new one on the server with production settings.
Optimize for Production
Before creating archives, optimize your Laravel application for production:
# Install optimized dependencies (no dev packages)
composer install --optimize-autoloader --no-dev
# Cache configuration, routes, and views
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Create production-ready ZIP archive
zip -r laravel-app.zip . -x "*.git*" "node_modules/*" "tests/*" ".env"Step 2: Upload Files to cPanel
2A: Upload Root Files (Outside public_html)
Access File Manager: Log into cPanel and open File Manager
Navigate to Root: Go to your home directory (not public_html)
Create App Directory: Create a new folder (e.g., "laravel_app")
Upload & Extract: Upload your root files archive and extract it
Directory Structure After Upload:
2B: Upload Public Files (Inside public_html)
Navigate to public_html: This is your web-accessible directory
Upload Public Archive: Upload your public folder contents
Extract Files: Extract directly into public_html (not in a subfolder)
Make sure index.php is directly in public_html, not in a subfolder. This ensures your site loads at your domain root.
Alternative: FilezIlla Upload Method
For faster uploads and easier management, use FilezIlla FTP client instead of cPanel File Manager.
📥 Upload Steps:
- 1. Connect to your hosting via FTP
- 2. Upload laravel-app.zip to home directory
- 3. Extract using cPanel File Manager
- 4. Run deployment scripts via SSH
⚡ Benefits:
- • Faster upload speeds
- • Resume interrupted uploads
- • Batch file operations
- • Better file management
Host: ftp.yourdomain.com (or your server IP)
Username: your_cpanel_username
Password: your_cpanel_password
Port: 21 (or 22 for SFTP)
Protocol: FTP or SFTP (recommended)Step 3: Setup Database
3A: Create MySQL Database
Access MySQL Databases: In cPanel, find "MySQL Databases"
Create Database: Enter database name (e.g., "laravel_db")
Create User: Add MySQL user with strong password
Assign User: Grant ALL PRIVILEGES to user for database
Database Credentials
username_laravel_dbusername_dbuseryour_secure_passwordlocalhost3B: Import Database
Export Local Database: Use phpMyAdmin locally to export your database as SQL
Access phpMyAdmin: In cPanel, open phpMyAdmin
Select Database: Choose the database you created
Import SQL File: Go to Import tab and upload your SQL file
If your SQL file is large, consider compressing it or breaking it into smaller chunks. Most shared hosts have file size limits.
Step 4: Configure Laravel for Production
4A: Update index.php Path References
The index.php file in your public_html needs to point to your Laravel application directory.
Original Code:
require __DIR__.'/../vendor/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php';
<?php
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Check If Application Is Under Maintenance
|--------------------------------------------------------------------------
*/
if (file_exists(__DIR__.'/../laravel_app/storage/framework/maintenance.php')) {
require __DIR__.'/../laravel_app/storage/framework/maintenance.php';
}
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
*/
require __DIR__.'/../laravel_app/vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
*/
$app = require_once __DIR__.'/../laravel_app/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
*/
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
)->send();
$kernel->terminate($request, $response);Replace "laravel_app" with whatever you named your application directory in Step 2A.
4B: Create Production .env File
Create a new .env file in your Laravel application directory with production settings.
APP_NAME="Your Laravel App"
APP_ENV=production
APP_KEY=base64:your_app_key_here
APP_DEBUG=false
APP_URL=https://yourdomain.com
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=error
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=username_laravel_db
DB_USERNAME=username_dbuser
DB_PASSWORD=your_secure_password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"- • Set
APP_DEBUG=false - • Use
APP_ENV=production - • Generate strong APP_KEY
- • Use secure database credentials
Run locally then copy:
php artisan key:generate --show4C: Ensure Proper .htaccess Configuration
Make sure your .htaccess file in public_html is properly configured for Laravel.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>This .htaccess ensures clean URLs and proper routing for your Laravel application.
Step 5: Set Proper File Permissions
Critical Permission Settings
Required Permissions:
755755644644How to Set Permissions:
Right-click folder in File Manager
Select "Change Permissions"
Enter numeric value or use checkboxes
Check "Recurse into subdirectories" for folders
Never set permissions to 777. This makes your files writable by everyone and is a major security risk.
Advanced: Deployment Scripts
Automated Deployment Script
If you have SSH access, use this script for automated deployment:
#!/bin/bash
# Laravel Deployment Script for cPanel Shared Hosting
echo "🚀 Starting Laravel deployment..."
# Step 1: Set proper permissions
echo "📁 Setting file permissions..."
chmod -R 775 ~/laravel-app/storage
chmod -R 775 ~/laravel-app/bootstrap/cache
# Step 2: Navigate to Laravel directory
cd ~/laravel-app
# Step 3: Run database migrations
echo "🗄️ Running database migrations..."
php artisan migrate --force
# Step 4: Clear and recache everything
echo "🧹 Clearing caches..."
php artisan config:clear
php artisan view:clear
php artisan route:clear
echo "💾 Rebuilding caches..."
php artisan config:cache
php artisan view:cache
php artisan route:cache
echo "✅ Deployment completed successfully!"Update Deployment Script
For updating existing deployments while preserving .env file:
#!/bin/bash
# Laravel Update Script - Preserves .env file
echo "🔄 Starting Laravel update..."
# Step 1: Backup .env file
cp laravel-app/.env laravel-app/.env.backup
# Step 2: Clean Laravel directory (except .env)
find laravel-app -mindepth 1 -not -name '.env' -exec rm -rf {} +
# Step 3: Restore .env backup
mv laravel-app/.env.backup laravel-app/.env
# Step 4: Extract new version
unzip public_html/laravel-app.zip -d laravel-app
# Step 5: Move ZIP file
mv public_html/laravel-app.zip .
# Step 6: Sync public files (preserve index.php modifications)
rsync -av --exclude='index.php' laravel-app/public/ public_html/
echo "✅ Update completed successfully!"Step 6: Testing & Troubleshooting
Test Your Deployment
✅ Check These Items:
- Homepage loads without errors
- Database connections work
- CSS and JS assets load properly
- User authentication works
- Form submissions function
- File uploads work (if applicable)
🔍 Common Issues:
- 500 Internal Server Error
- 404 Not Found on routes
- Database connection errors
- Missing CSS/JS files
- Permission denied errors
- Session/cache issues
Troubleshooting Common Issues
500 Internal Server Error
Possible Causes:
- • Incorrect file paths in index.php
- • Wrong file permissions
- • Missing .env file
- • Invalid APP_KEY
- • PHP version incompatibility
Solutions:
- • Check error logs in cPanel
- • Verify index.php paths
- • Set storage/ to 755 permissions
- • Generate new APP_KEY
- • Contact hosting support for PHP version
Database Connection Errors
Check These Settings:
- • Database name (with username prefix)
- • Database username (with prefix)
- • Database password
- • Host (usually localhost)
- • Port (usually 3306)
Verify Database:
- • Database exists in phpMyAdmin
- • User has proper privileges
- • Tables imported correctly
- • .env credentials match cPanel
Missing CSS/JS Assets
Common Causes:
- • Assets not compiled for production
- • Incorrect asset URLs
- • Missing public folder files
- • .htaccess issues
Solutions:
- • Run
npm run buildlocally - • Check APP_URL in .env
- • Verify public files uploaded
- • Ensure .htaccess is present
Security Best Practices for Production
Essential Security Measures
- Enable HTTPS: Use SSL certificate for encrypted connections
- Hide .env File: Ensure it's not web-accessible
- Regular Updates: Keep Laravel and dependencies updated
- Strong Passwords: Use complex database and admin passwords
- Backup Strategy: Implement regular backups
Performance Optimization
- Enable Caching: Configure cache drivers for better performance
- Optimize Assets: Minify CSS/JS and optimize images
- Database Optimization: Use indexes and optimize queries
- Enable Compression: Use Gzip compression for faster loading
- Monitor Performance: Set up logging and monitoring
Security Hardening Script
Run this script to enhance security after deployment:
#!/bin/bash
# Laravel Security Hardening Script
echo "🔒 Applying security hardening..."
# Set secure file permissions
find ~/laravel-app -type f -exec chmod 644 {} \;
find ~/laravel-app -type d -exec chmod 755 {} \;
# Make specific directories writable
chmod -R 775 ~/laravel-app/storage
chmod -R 775 ~/laravel-app/bootstrap/cache
# Secure .env file
chmod 600 ~/laravel-app/.env
# Remove sensitive files from public access
rm -f ~/public_html/.env
rm -f ~/public_html/composer.json
rm -f ~/public_html/composer.lock
echo "✅ Security hardening completed!"Ongoing Maintenance
Regular Backups
- • Schedule automatic backups
- • Test backup restoration
- • Store backups off-site
- • Include database and files
Updates
- • Monitor Laravel releases
- • Update dependencies regularly
- • Test updates on staging first
- • Keep PHP version current
Monitoring
- • Check error logs regularly
- • Monitor site uptime
- • Watch for security issues
- • Track performance metrics
Conclusion
Congratulations! You've successfully deployed your Laravel application to shared hosting using cPanel. This deployment method provides a cost-effective way to host Laravel applications while maintaining proper security and performance standards.
✅ What You've Accomplished:
- • Properly structured file deployment
- • Secure production configuration
- • Database setup and migration
- • Correct file permissions
- • Security best practices implementation
- • Automated deployment scripts
🚀 Next Steps:
- • Set up SSL certificate
- • Configure automated backups
- • Implement monitoring
- • Optimize for performance
- • Plan update strategy
- • Set up staging environment
Remember: While shared hosting is great for getting started, consider upgrading to VPS or dedicated servers as your application grows and requires more resources or advanced features.
