BabalCloud Logo
PricingAboutBlog
Log inGet Started
BabalCloud

Empowering businesses with reliable, scalable, and secure cloud hosting solutions. Our infrastructure is designed for performance, uptime, and peace of mind.

Products

  • Pricing
  • Domain Registration
  • Domain Transfer

Company

  • About Us
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 BabalCloud Private Limited. All rights reserved.

Proudly serving developers in Nepal.

Back to blog
Developers

How to Deploy a Laravel App to cPanel Shared Hosting (2026)

A step-by-step guide to deploying Laravel on cPanel shared hosting the right way — fixing the public folder, setting up the database and .env, running migrations, and automating it with GitHub Actions.

BabalCloud TeamJuly 22, 20267 min read

Deploying Laravel to shared hosting has a reputation for being painful — mostly because Laravel expects the public folder to be the web root, and cPanel serves everything from public_html. Get that one thing right and the rest is straightforward. This guide walks through the whole process, from uploading your code to running migrations, plus how to automate future deploys so you never repeat these steps by hand.

Everything here works on standard cPanel shared hosting. You do not need a VPS — though you do need a plan that runs a modern PHP version and, ideally, gives you SSH or Terminal access.

Choosing a host for your Laravel project? BabalCloud plans ship with PHP version control, SSH/Terminal access, and an automated GitHub-to-cPanel pipeline — the exact things that make Laravel deployment painless. See pricing or how deployment works.

The core problem: Laravel's public folder vs cPanel's public_html

In a Laravel project, only the public directory should ever be reachable from the web. Everything else — your .env file, routes, config, database credentials — must stay private. But on cPanel, the folder that's served to visitors is public_html. So the whole job of "deploying Laravel to cPanel" comes down to bridging those two facts without exposing your application files.

There are two clean ways to do it. Pick the one that matches your access level.

What you'll need before deploying

  • A Laravel project that runs locally without errors.
  • A cPanel hosting account with PHP 8.2 or higher (check under MultiPHP Manager or Select PHP Version).
  • Your app's Composer dependencies installable on the server (or uploaded).
  • Access to phpMyAdmin (for the database) and ideally Terminal/SSH (for artisan commands).

Confirm your PHP version first — Laravel 11 and 12 need PHP 8.2+, and deploying onto an old PHP build is the most common cause of a white screen.

Method 1: Keep the app outside public_html (recommended)

This is the correct, secure approach. Your Laravel app lives in a private folder, and only its public contents are exposed.

Step 1 — Upload your project

Zip your Laravel project locally (exclude node_modules and vendor to keep it small), then in cPanel File Manager, upload and extract it to a folder above the web root — for example /home/username/laravelapp/, not inside public_html.

Step 2 — Install dependencies on the server

If you have Terminal/SSH access, run inside the project folder:

composer install --optimize-autoloader --no-dev

No SSH? Then include the vendor folder in your upload instead — build it locally with the same command first, then upload it with the rest of the project.

Step 3 — Move the public folder's contents into public_html

Copy everything inside your project's public folder into public_html. Then open public_html/index.php and update the two paths that point back to your app:

// Point these at your app folder, one level up from public_html
require __DIR__.'/../laravelapp/vendor/autoload.php';
 
$app = require_once __DIR__.'/../laravelapp/bootstrap/app.php';

Now visitors hit public_html/index.php, which boots the app that safely lives in laravelapp/ — exactly the separation Laravel wants.

Step 4 — Create the database

In cPanel, open MySQL Databases and create a database and a user, then add the user to the database with All Privileges. Note the database name, username, and password — they're prefixed with your cPanel account name (e.g. cpuser_appdb).

Step 5 — Configure your .env

Edit .env in your laravelapp/ folder with production values:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
 
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=cpuser_appdb
DB_USERNAME=cpuser_appuser
DB_PASSWORD=your-strong-password

Set APP_DEBUG=false in production — leaving it on exposes stack traces and config to the public. If your app key is empty, generate one with php artisan key:generate.

Step 6 — Run migrations and cache config

Over SSH/Terminal, from the app folder:

php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan storage:link

--force is required because production migrations otherwise ask for confirmation. No SSH access? You can import your schema through phpMyAdmin, but running artisan is far cleaner — it's worth choosing a host that gives you Terminal access.

Method 2: Symlink public_html to the public folder

If your host lets you delete and recreate public_html as a symlink, you can skip editing index.php entirely. Over SSH:

rm -rf ~/public_html
ln -s ~/laravelapp/public ~/public_html

Now public_html is Laravel's public folder. This is the tidiest setup, but some shared hosts disable symlink creation — if the command fails, use Method 1.

Automate it: deploy on every git push

Doing all of the above once is fine. Doing it on every change is not. Wire up GitHub Actions so that pushing to main deploys automatically. Here's a minimal SSH-based workflow that syncs files and runs post-deploy commands:

name: Deploy Laravel to cPanel
 
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Deploy over SSH
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd ~/laravelapp
            git pull origin main
            composer install --optimize-autoloader --no-dev
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache

Store SSH_HOST, SSH_USER, and SSH_PRIVATE_KEY as repository secrets (GitHub → Settings → Secrets and variables → Actions). For the full walkthrough of setting up these keys and secrets, see our guide on auto-deploying from GitHub to cPanel.

Troubleshooting

White screen / HTTP 500. Almost always a PHP version mismatch or a missing vendor folder. Set PHP to 8.2+ in cPanel and confirm dependencies are installed. Temporarily set APP_DEBUG=true to read the real error, then turn it back off.

"No application encryption key has been specified." Run php artisan key:generate, or set a valid APP_KEY in .env.

403 Forbidden or directory listing instead of the app. Your web root isn't pointing at the public folder. Recheck Step 3 or the symlink in Method 2.

Storage/permission errors. Laravel needs to write to storage/ and bootstrap/cache/. Set those folders to 755 and ensure they're owned by your cPanel user.

Images/uploads return 404. Run php artisan storage:link so public/storage points to storage/app/public.

Frequently asked questions

Can Laravel really run on shared hosting, or do I need a VPS?

For most small-to-medium apps, shared cPanel hosting is perfectly capable of running Laravel. You'll want a VPS only when you need queue workers, custom services, or heavy background processing that shared plans limit.

What PHP version does Laravel need?

Laravel 11 and 12 require PHP 8.2 or newer. Always check and set the PHP version in cPanel before deploying — it's the number-one cause of deployment failures.

How do I run queue workers on shared hosting?

Use a cron job in cPanel to run php artisan schedule:run every minute, and process queues with queue:work --stop-when-empty triggered on a schedule, since shared hosts don't allow always-on daemons.

Do I need SSH access?

Not strictly, but it makes everything easier — running migrations, clearing caches, and installing Composer packages. If you can, choose a plan that includes Terminal or SSH access.

How do I deploy Laravel updates without downtime?

Automate deployment with GitHub Actions (above) and run php artisan config:cache and route:cache after each deploy. Because your code is in Git, rolling back a broken release is just a git revert and push.

Summary

Deploying Laravel to cPanel is really just three ideas: keep the app private, expose only the public folder, and run your migrations and caches after each deploy. Do it once by hand to understand it, then automate it with GitHub Actions so future releases are one git push.

If you want a host where PHP versions, SSH access, and automated GitHub deployment are built in rather than bolted on, take a look at BabalCloud's hosting plans — they're designed for exactly this developer workflow.

#Laravel#cPanel#Deployment#PHP#Web Hosting
Share

On this page

  • The core problem: Laravel's public folder vs cPanel's publichtml
  • What you'll need before deploying
  • Method 1: Keep the app outside publichtml (recommended)
  • Step 1 — Upload your project
  • Step 2 — Install dependencies on the server
  • Step 3 — Move the public folder's contents into publichtml
  • Step 4 — Create the database
  • Step 5 — Configure your .env
  • Step 6 — Run migrations and cache config
  • Method 2: Symlink publichtml to the public folder
  • Automate it: deploy on every git push
  • Troubleshooting
  • Frequently asked questions
  • Can Laravel really run on shared hosting, or do I need a VPS?
  • What PHP version does Laravel need?
  • How do I run queue workers on shared hosting?
  • Do I need SSH access?
  • How do I deploy Laravel updates without downtime?
  • Summary