You built your Laravel app locally. It runs perfectly. Now you want to put it online. And that's where things get confusing.
Laravel isn't like plain HTML. You can't just drag the project folder into public_html and expect it to work. The biggest problem? Laravel's entry point is inside the public/ folder, not the root. Shared hosting like Hostinger points the domain to public_html by default. So you must either move the public files to the root, or use a redirect.
In this guide, I'll show you two complete methods: manual upload (File Manager/FTP) and Git deployment (SSH). Both work on Hostinger and any cPanel-based host. I'll also show the exact .htaccess trick and the symlink method to solve the public folder problem.
No fluff. Just the steps that actually work.
What You Need Before Starting
- ✅ A Laravel project that runs on your local machine.
- ✅ A hosting account (Hostinger, Namecheap, or any cPanel host).
- ✅ A domain pointed to your hosting.
- ✅ A database (MySQL, PostgreSQL, or SQLite).
- ✅ Correct PHP version (Laravel 11 needs PHP 8.2+).
- ✅ Composer installed locally.
- ✅ SSH access enabled (for the Git method).
Hostinger's Web and Cloud hosting plans support all of these. If you're on a very cheap plan without SSH, use the manual method instead.
Understanding the Problem: Why public/ Breaks Everything
When someone visits yourdomain.com, the web server looks for files in public_html.
But Laravel's index.php (the file that starts the app) is inside the public/ folder. Your actual application code (controllers, models, views) sits outside the public folder, for security.
So you have two choices:
- Move the contents of
public/topublic_htmland editindex.phpto point to the real app folder. - Keep everything outside
public_htmland use a.htaccessredirect or a symbolic link.
The Hostinger official guide recommends moving the public folder contents to public_html and adding a redirect rule. The symlink method is also popular on shared hosting.
I'll show you both so you can pick what works for your setup.
Method 1: Manual Upload (File Manager / FTP)
This is the easiest method if you don't want to use SSH. You'll use Hostinger's File Manager or an FTP client like FileZilla.
Step 1: Prepare Your Files Locally
Before uploading, run these commands in your local project folder:
composer install --no-dev --optimize-autoloader
npm run build
This creates the vendor/ folder (without dev dependencies) and compiles your CSS/JS assets into public/build/.
If you don't have Node.js locally, you can skip npm run build and upload the compiled assets manually. But the vendor/ folder is required—you can't run Laravel without it.
Step 2: Upload the Project Outside public_html
Open Hostinger's File Manager. You'll see a public_html folder.
Create a new folder next to it, for example laravel_app.
Upload your entire Laravel project into this laravel_app folder. Do not upload it inside public_html.
Your structure should look like this:
/home/yourusername/
├── public_html/ ← Website root
└── laravel_app/ ← Full Laravel project
├── app/
├── bootstrap/
├── config/
├── database/
├── public/ ← Entry point
├── resources/
├── routes/
├── storage/
├── vendor/
├── .env
└── ...
Step 3: Move public/ Contents to public_html
Now open the laravel_app/public/ folder.
Move all files from public/ to public_html/. This includes index.php, .htaccess, robots.txt, and the build/ folder.
Do not move the public folder itself—move only the contents.
Step 4: Edit public_html/index.php
Open public_html/index.php in the File Manager editor.
You need to change two lines that point to the vendor and bootstrap folders. Find these lines:
require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
Change them to point to your laravel_app folder:
require __DIR__.'/../laravel_app/vendor/autoload.php';
$app = require_once __DIR__.'/../laravel_app/bootstrap/app.php';
If your folder is named differently, adjust the path accordingly.
Step 5: Verify .htaccess in public_html
Since you moved the default Laravel .htaccess along with the public files, it should already be inside public_html.
Make sure it contains the front controller rule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
This file handles all routing. No extra rule needed since the public files are already in the root.
Step 6: Set Up Your .env File
In laravel_app, open the .env file.
Update these values:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password
Create the database in Hostinger's hPanel first (MySQL Databases section).
Step 7: Run Migrations and Clear Cache
Connect via SSH (Hostinger gives you SSH access in hPanel).
Navigate to your project:
cd ~/laravel_app
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
If you don't have SSH, you can run these commands via a temporary route in routes/web.php:
Route::get('/run-migrate', function () {
Artisan::call('migrate', ['--force' => true]);
Artisan::call('config:cache');
return 'Done';
});
Delete this route immediately after use.
Step 8: Set Folder Permissions
Laravel needs write access to storage/ and bootstrap/cache/.
Via SSH:
chmod -R 775 storage bootstrap/cache
Via File Manager: right-click the folder → Permissions → set to 775.
Method 2: Git Deployment via SSH (Recommended for Updates)
Manual upload works for the first deploy. But for updates, Git is much faster. You push to GitHub, then pull on the server.
Step 1: Enable SSH on Hostinger
In hPanel, go to Advanced → SSH Access. Enable it and set a password.
You'll get a command like:
ssh -p 65002 u123456789@123.123.123.123
Use this to connect from your terminal.
Step 2: Clone Your Repository on the Server
Once connected via SSH, navigate to the folder one level above public_html:
cd ~/
git clone https://github.com/yourusername/your-repo.git laravel_app
cd laravel_app
If the repo is private, use a personal access token or SSH key.
Step 3: Install Dependencies
composer install --no-dev --optimize-autoloader
Step 4: Set Up the Symlink (The Clean Way)
Instead of moving files, you can create a symbolic link. This means public_html becomes a shortcut to your public/ folder.
First, remove the existing public_html folder (make sure it's empty or backed up):
cd ~/
rm -rf public_html
ln -s ~/laravel_app/public ~/public_html
Now public_html points directly to your Laravel public/ folder. No file moving, no index.php editing.
Note: Some shared hosts don't allow symlinks. If it doesn't work, use the .htaccess method instead.
Step 5: Set Permissions and Run Artisan
chmod -R 775 storage bootstrap/cache
php artisan key:generate
php artisan migrate --force
php artisan config:cache
Step 6: Future Deployments (One Command)
Whenever you push changes to GitHub, just SSH in and run:
cd ~/laravel_app
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
That's it. Your site is updated.
Alternative: .htaccess Redirect (No File Moving)
If you don't want to move files or create symlinks, you can keep everything inside public_html and add a redirect rule.
Structure: upload your entire Laravel project into public_html/laravel_app/. Then create a .htaccess in public_html with this rule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ laravel_app/public/$1 [L]
</IfModule>
This tells the server: "For every request, look inside laravel_app/public/."
The Hostinger official guide uses a similar rule (RewriteRule ^(.*)$ public/$1 [L]) when the Laravel folder is the root. Adjust the path to match your folder name.
Pros: No file moving. Easy to update.
Cons: Your app code is inside public_html, which is slightly less secure (though .htaccess rules can block direct access).
Common Errors and Fixes
Error: 403 Forbidden
Cause: Missing index.php or wrong file permissions.
Fix: Make sure index.php is in public_html. Set folder permissions to 755 and file permissions to 644.
Error: 500 Internal Server Error
Cause: Wrong .htaccess rules, missing .env, or storage permissions.
Fix: Check .htaccess syntax. Ensure .env exists and has APP_KEY. Run chmod -R 775 storage bootstrap/cache.
Error: "Vite manifest not found"
Cause: You forgot to run npm run build before uploading.
Fix: Run npm run build locally, then upload the public/build/ folder.
Error: Database Connection Refused
Cause: Wrong DB credentials in .env.
Fix: Double-check DB_HOST (usually localhost on Hostinger), DB_DATABASE, DB_USERNAME, and DB_PASSWORD.
Error: Routes Not Working (404 on all pages except home)
Cause: Missing or wrong .htaccess file.
Fix: Ensure the default Laravel .htaccess is in public_html. It should contain the front controller rule:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Frequently Asked Questions
Can I deploy Laravel on Hostinger's cheapest plan?
Yes, but only the manual method. The cheapest plans may not have SSH access, so you can't run git pull or php artisan commands directly. You'll need to use temporary routes or the File Manager.
Do I need to move the public folder?
Not necessarily. You can use the .htaccess redirect method instead. But moving the files is the most common approach and works on all hosts.
What's better: symlink or moving files?
Symlink is cleaner because you don't have to edit index.php or worry about paths. But some shared hosts disable symlinks. If symlink doesn't work, move the files.
How do I update my site after the first deploy?
With Git: push to GitHub, SSH into the server, run git pull and composer install. With manual: re-upload changed files via FTP.
Can I use this guide for other hosting providers?
Yes. The steps are the same for any cPanel-based host: Namecheap, Bluehost, SiteGround, etc. The only difference is the control panel name (hPanel vs cPanel).
Is it safe to keep the app outside public_html?
Yes — it's actually more secure. Your .env file, database credentials, and source code are not web-accessible.
Do I need to run npm run build on the server?
No. Run it locally and upload the public/build/ folder. Most shared hosts don't have Node.js installed, and building on the server is slow and unnecessary.
Final Words
Deploying Laravel on shared hosting isn't hard. It's just different from local development.
The key is handling the public/ folder correctly. Pick one method:
- Symlink: Cleanest. Best if your host allows it.
- Move files: Most common. Works everywhere.
- .htaccess redirect: Easiest. No file moving.
Once your first deploy is done, updates are simple. With Git, it's just git pull and composer install.
Need to check if your deployed site is live? Use our link checker to verify URLs, or our JSON formatter if you're debugging API responses.
More Developer Guides
From password security to JSON formatting — we've got you covered.