Deploying a Laravel App to Shared Hosting: Complete Guide

Shared hosting is the most affordable way to publish a Laravel app, but many beginners stumble because its structure differs from localhost. The most common problems: the entire pr...

Deploying a Laravel App to Shared Hosting: Complete Guide

Shared hosting is the most affordable way to publish a Laravel app, but many beginners stumble because its structure differs from localhost. The most common problems: the entire project becomes publicly visible, or a blank white screen appears with no message. This guide walks you from upload to a securely running app on cPanel, focusing on two key points: pointing the document root at the public folder and setting up a production .env correctly.

1. Prepare the Project Before Upload

Before copying anything, make sure your local project is tidy. Run the front-end asset build if you have one:

npm run build

Do not include the vendor and node_modules folders in the upload — both are large and can be rebuilt on the server. Compress the project into a single ZIP file so the upload is faster and no files are missed.

2. Upload and Extract via File Manager

Log into cPanel and open File Manager. Upload the ZIP to a folder outside public_html — for example, create a new folder named laravel in the home directory and extract there. Keeping the application code outside public_html is important for security: only the public folder should be publicly accessible.

3. Point the Document Root at the public Folder

This is the most crucial step. Laravel is designed so that only the public folder is the web root; everything else (code, config, the .env file) must stay hidden.

If you use the primary domain, the easiest approach is to copy the contents of public into public_html, then edit public_html/index.php so it points to the application location:

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

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

If your host supports changing the document root per domain (via the Domains menu), it is cleaner to point it directly at /home/user/laravel/public without moving any files.

4. Install Dependencies with Composer

Open the Terminal menu in cPanel (or SSH). Enter the application folder and run Composer without development dependencies for a leaner install:

cd ~/laravel
composer install --optimize-autoloader --no-dev

The --no-dev flag skips packages only needed during development, and --optimize-autoloader speeds up class loading in production. If your host offers no terminal, some providers have a "Run Composer" button in the panel, or you can upload the vendor folder manually.

5. Set Up the Production .env File

Copy .env.example to .env, then fill it with production settings. The first three lines determine the app's security:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=database_name
DB_USERNAME=database_user
DB_PASSWORD=secret_password

Mandatory: APP_DEBUG=false. If left as true, any error will display code details, server paths, and even database credentials to visitors. Fill the database credentials with the ones you created in cPanel's MySQL Databases menu.

6. Generate the Application Key

Laravel needs a unique encryption key to secure sessions and encrypted data. Generate it with:

php artisan key:generate

This command fills APP_KEY in .env. Without a valid key, you will get the error "No application encryption key has been specified".

7. Run the Database Migrations

Once the database and credentials are ready, create all the tables. In production Laravel asks for confirmation; skip it with --force:

php artisan migrate --force

If you have initial data (seeders), run php artisan db:seed --force.

8. Set Permissions for storage and bootstrap/cache

Laravel needs to write to these two folders for logs, cache, and uploaded files. Grant write permission:

chmod -R 775 storage bootstrap/cache

If the app displays images or uploaded files, create a symbolic link from storage to public:

php artisan storage:link

On some shared hosts storage:link fails due to symlink restrictions; if so, you can create the link manually via File Manager or copy the folder.

9. Cache Config and Routes for Speed

The final step speeds up the app by merging config and routes into a single cache file:

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

Remember: whenever you change .env later, re-run php artisan config:cache, or clear it with php artisan config:clear, so the changes take effect.

Checklist When Problems Arise

  • White screen / 500 error: check storage/logs/laravel.log. Temporarily set APP_DEBUG=true, fix it, then return to false.
  • All files visible in the URL: the document root does not point to public.
  • "Permission denied": storage or bootstrap/cache is not set to 775.
  • .env changes have no effect: an old config cache is still active — run config:clear.

With these nine steps your Laravel app is live and secure on shared hosting: code hidden, debug off, database migrated, and config cached for speed. Keep the checklist above to speed up troubleshooting on your next deploy.

Yudhi
Written by
Yudhi
Founder & Lead Developer, GudangCode

Yudhi is the founder of GudangCode and a Laravel developer who has built dozens of ready-to-use business information systems — from POS and HRIS to management apps. He writes guides and articles on GudangCode to help Indonesian developers run, understand, and deploy Laravel source code correctly.

LaravelPHPMySQLSistem Informasi Bisnis See all articles by Yudhi
Want the full source code & apps?

Sign up free to download ready-to-use business applications, information systems, and Laravel source code.

Sign Up Free & Download
Laravel Deploy Hosting DevOps
Share this article
Back to Blog
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →

Get Full Access Now!

Join our membership and unlock exclusive access to all premium features. Fast, easy, and ready to use instantly.

Join Membership Now
Tim Support
Online
Isi data dulu untuk mulai chat:
Beri rating & testimoni sebelum menutup:
Live chat by gudangcode.com