Moniruzzaman Saikat

Posted Sep 29, 2026 · 5 min read · 1 view

Report

Deploying a Laravel App on Shared cPanel Hosting, Step by Step

Not every project gets a VPS. Many clients in Bangladesh run on shared cPanel hosting, and Laravel does not deploy there the way it does on a modern server. There is no public folder as the web root, SSH is sometimes missing, and symlinks may be blocked.

The good news is that Laravel runs perfectly well on cPanel once you set it up correctly. This guide walks through a safe, repeatable deployment.

What you need before you start

  • A cPanel hosting account with PHP 8.2 or newer available
  • Your Laravel project on your computer
  • A MySQL database created in cPanel
  • Optional but helpful: SSH or Terminal access in cPanel

Check your PHP version first. In cPanel, open MultiPHP Manager and select the PHP version your Laravel release requires. Also confirm that extensions like mbstring, openssl, pdo_mysql, tokenizer, xml, ctype, json, and fileinfo are enabled under Select PHP Version.

Step 1: Prepare the project locally

Install production dependencies and build your assets before uploading:

composer install --optimize-autoloader --no-dev
npm run build

Now zip the project. Exclude node_modules, .git, and your local .env file. Uploading one zip is much faster and safer than uploading thousands of small files through FTP.

Step 2: Choose the right folder structure

This is the step most people get wrong. Do not put your whole Laravel project inside public_html. That would expose your .env, source code, and config files to the internet.

Use this structure instead:

/home/username/
  laravel-app/        <- everything except the public folder
  public_html/        <- contents of Laravel's public folder

Upload and extract your zip into /home/username/laravel-app. Then move the contents of laravel-app/public into public_html.

If you are deploying to a subdomain, replace public_html with the subdomain's document root, for example public_html/app or app.example.com.

Step 3: Fix the paths in index.php

Since public_html and laravel-app are now siblings, Laravel needs to know where to find the framework. Open public_html/index.php and update these lines:

require __DIR__.'/../laravel-app/vendor/autoload.php';

$app = require_once __DIR__.'/../laravel-app/bootstrap/app.php';

Also check the maintenance mode line near the top and point it to the new location:

if (file_exists($maintenance = __DIR__.'/../laravel-app/storage/framework/maintenance.php')) {
    require $maintenance;
}

Step 4: Configure the environment file

Create a .env file inside laravel-app and set production values:

APP_NAME="My App"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com

DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=cpanelusername_dbname
DB_USERNAME=cpanelusername_dbuser
DB_PASSWORD=your-strong-password

Two things to remember. First, APP_DEBUG must be false in production, otherwise errors expose secrets. Second, cPanel prefixes database and user names with your account name, so copy the full names exactly as cPanel shows them.

Generate an app key if you have not already:

php artisan key:generate

No SSH? Run it locally and paste the generated APP_KEY into your server's .env.

Step 5: Run migrations

With SSH or the cPanel Terminal, this is easy:

cd ~/laravel-app
php artisan migrate --force

Without terminal access, you have two options. You can export your local database and import the SQL file through phpMyAdmin, or you can create a temporary protected route that calls Artisan::call('migrate', ['--force' => true]). If you use the route approach, delete it immediately after use.

Step 6: Set permissions and storage

Laravel needs to write to storage and bootstrap/cache. Set folders to 755 and make sure your account owns them:

chmod -R 755 storage bootstrap/cache

Only use 775 if your host requires it. Never use 777.

Next, the storage link. The usual command is:

php artisan storage:link

On many shared hosts this fails because symlinks are disabled. In that case, create the link with a small PHP script or use a cPanel cron job that runs ln -s. A simple alternative is to change your filesystem disk in config/filesystems.php so the public disk points directly to a folder inside public_html.

Step 7: Cache for production

Once everything works, speed it up:

php artisan config:cache
php artisan route:cache
php artisan view:cache

Remember to clear and rebuild these caches after every deployment that changes config or routes.

Step 8: Add a cron job for the scheduler

If your app uses scheduled tasks or queues, add this in Cron Jobs in cPanel, set to run every minute:

* * * * * /usr/local/bin/php /home/username/laravel-app/artisan schedule:run >> /dev/null 2>&1

The PHP path may differ on your host, so confirm it with your provider.

Common problems and fixes

ProblemLikely causeFix
500 error on every pageWrong paths in index.php or missing .envRecheck Step 3 and Step 4
Blank white pageMissing PHP extension or wrong PHP versionCheck MultiPHP Manager
Images not loadingStorage link missingRedo the storage link fix
Routes return 404Missing .htaccess in public_htmlCopy it from Laravel's public folder
Permission denied errorsWrong storage permissionsSet 755 and check ownership

When something fails, open laravel-app/storage/logs/laravel.log. It almost always tells you the exact problem.

Security checklist

Before you announce the site is live, verify these:

  1. APP_DEBUG=false and APP_ENV=production
  2. .env is outside public_html
  3. SSL is enabled and HTTP redirects to HTTPS
  4. Directory listing is disabled
  5. Database password is strong and unique

Final thoughts

Shared hosting is not glamorous, but it is where a lot of real projects live. If you keep the app outside the web root, fix the paths in index.php, and handle storage and permissions carefully, Laravel runs smoothly on cPanel. Save these steps as a checklist and your next deployment will take minutes instead of hours.

Deploying on a tricky host? Share your setup in the comments and let us figure it out together.

Be the first to react
0

Written by

Moniruzzaman Saikat

Software Engineer at TheSoftking Ltd

Software engineer who loves building useful things, solving hard problems, and turning ideas into scalable products. Always learning, shipping, and experimenting with new tech.

Founding MemberNew MemberProlific Writer

14 articles · Dhaka Bangladesh · Joined Sep 2026

Discussion (0)

Sign in to join the discussion.