Laravel on Hostinger Shared Hosting

P2P Session Handout — Basics

Part 1 — Laravel Basics

1. What is Laravel?

Laravel is a PHP framework for building web applications. It gives you:

2. Basic Requirements

Before you start, make sure you have:

3. Create a New Laravel Project (Local)

Open your terminal and run:

composer create-project laravel/laravel myapp
cd myapp
php artisan serve

Open http://localhost:8000 in your browser.
If you see the Laravel welcome page — it works.

4. Understanding the Important Folders

Folder / FileWhat it does
app/Your application code
routes/Where URLs are defined
config/Configuration files
storage/Logs, cache, uploaded files (must be writable)
bootstrap/cache/Compiled config (must be writable)
public/Web-accessible folder (index.php lives here)
.envEnvironment settings (never share this!)

5. The .env File

.env holds settings that change between environments (local vs production).

Example:

APP_NAME=MyApp
APP_ENV=local
APP_KEY=base64:xxxxxxxxxxxxxx
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=
Important rules
  • Never commit .env to Git
  • APP_DEBUG=true only for local development
  • APP_DEBUG=false always for production
  • Run php artisan key:generate if APP_KEY is empty

6. Useful Artisan Commands

These are the commands you will use most often:

# Generate the app encryption key
php artisan key:generate

# Run database migrations
php artisan migrate

# Create the public storage symlink (for uploaded files)
php artisan storage:link

# Clear cached config (use after editing .env)
php artisan config:clear

# Clear application cache
php artisan cache:clear

# Clear route cache
php artisan route:clear

# Clear view cache
php artisan view:clear

# Clear everything at once
php artisan optimize:clear
Tip If you edit .env and nothing changes, run php artisan config:clear.

7. Storage Permissions

Laravel needs to write to two folders:

If you see this error:

failed to open stream: Permission denied

Fix it with:

chmod -R 775 storage bootstrap/cache
Part 2 — Deploying to Hostinger

8. The Main Challenge

Laravel expects public/ as the document root.
Hostinger uses public_html/ as the document root.

⚠ Security Warning Never dump the whole Laravel project inside public_html/ — your .env and source files will be exposed to the internet.

We have two safe options — but first, let's understand how Hostinger organizes files.

9. Understanding Hostinger's Directory Structure

When you SSH into your Hostinger account, this is what you'll typically see:

$ pwd
/home/u325800960/domains/yourdomain.com

$ ls -la
drwxr-xr-x  .
drwxr-xr-x  ..
-rw-r--r--  DO_NOT_UPLOAD_HERE
drwxr-xr-x  public_html

Breaking down the path:

PartMeaning
/home/u325800960/Your Hostinger user home directory (the number is your user ID)
domains/yourdomain.com/Root folder for this specific domain
DO_NOT_UPLOAD_HEREMarker file — reminds you NOT to upload website files at this level
public_html/This is where your website files go. Anything here is served on the web
Why the DO_NOT_UPLOAD_HERE file? Files placed in the domain root (one level above public_html/) are NOT served by the web server. Beginners often upload files here by mistake and wonder why the site is blank. This is actually a great place to store your Laravel project if you use Option A (see section 11).

10. Using Hostinger's Laravel Auto-Installer

Hostinger provides a one-click Laravel installer in hPanel. When you use it, this is what you get inside public_html/:

public_html/
├── app/
├── artisan
├── bootstrap/
├── composer.json
├── composer.lock
├── config/
├── database/
├── default.php
├── .editorconfig
├── .env                  ← permissions 600 (secure)
├── .env.example
├── .htaccess             ← auto-generated redirect
├── index.php             ← auto-generated entry
├── package.json
├── phpunit.xml
├── public/
├── README.md
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
└── vite.config.js

What does this mean?

Security note Because everything is inside public_html/, the source code is technically reachable if the .htaccess stops working (e.g., mod_rewrite disabled). Always keep .env permissions at 600, and consider migrating to Option A for higher-security production sites.

The auto-generated .htaccess

Hostinger's installer creates a .htaccess similar to this at public_html/.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

The auto-generated index.php

A small index.php at public_html/index.php handles requests that don't match the rewrite. It typically just includes the real one:

<?php
require __DIR__ . '/public/index.php';
If the auto-installer worked, you can skip Option A / Option B setup. Just update .env, run the Artisan commands (section 13, Step 5), and your app is live.

11. Option A — Project Outside public_html (Most Secure)

Folder structure on Hostinger:

/home/username/
├── laravel_app/          ← full Laravel project here
│   ├── app/
│   ├── config/
│   ├── .env
│   └── public/
└── public_html/          ← only public/ contents here
    ├── index.php         (edited to point to ../laravel_app)
    └── .htaccess

Edit public_html/index.php and change these two lines:

require __DIR__.'/../laravel_app/vendor/autoload.php';
$app = require_once __DIR__.'/../laravel_app/bootstrap/app.php';

12. Option B — Use .htaccess Redirect (Same as Auto-Installer)

Upload the whole Laravel project into public_html/ and create a .htaccess file at the root of public_html/:

<IfModule mod_rewrite.c>
    RewriteEngine On
    # Redirect everything to Laravel public folder
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

This tells Apache: any request that is not already for /public/ should be redirected into the public/ folder.

Easier to set up, but Option A is safer.

13. Step-by-Step Deployment

Step 1 — Prepare your project locally

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

Then zip the whole project folder.

Step 2 — Upload to Hostinger

Step 3 — Create the database

Step 4 — Update .env on the server

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

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=u123456789_myapp
DB_USERNAME=u123456789_user
DB_PASSWORD=your_password
Note Use localhost, NOT 127.0.0.1 on Hostinger.

Step 5 — Run Artisan commands (via SSH)

php artisan key:generate
php artisan migrate --force
php artisan storage:link
php artisan config:clear
php artisan cache:clear

If your plan has no SSH, run these as one-time Cron Jobs from hPanel.

14. Common Errors on Hostinger

ErrorCauseFix
Blank white pageAPP_DEBUG=false hiding real errorSet APP_DEBUG=true temporarily, check storage/logs/laravel.log
"No application encryption key"APP_KEY emptyRun php artisan key:generate
"Access denied for user"Forgot u<id>_ prefix on DB userCopy exact name from hPanel
"Connection refused"Used 127.0.0.1Change to DB_HOST=localhost
Changes to .env not appliedConfig is cachedRun php artisan config:clear
500 error, permission deniedstorage/ not writablechmod -R 775 storage bootstrap/cache
Uploaded images not showingMissing storage symlinkRun php artisan storage:link
Assets (CSS/JS) missingForgot npm run buildBuild locally, re-upload public/build/

15. Final Deployment Checklist

16. Quick Reference — Commands Cheat Sheet

# Setup
composer install --optimize-autoloader --no-dev
php artisan key:generate
php artisan migrate --force
php artisan storage:link

# Clear caches (use when things "don't update")
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear

# Or clear all at once
php artisan optimize:clear

# Permissions (if needed)
chmod -R 775 storage bootstrap/cache