DEV Community

Cover image for Deploy Your Laravel Demo for Free — Domain, MySQL & Hosting at $0
Antonios Thanasis
Antonios Thanasis

Posted on

Deploy Your Laravel Demo for Free — Domain, MySQL & Hosting at $0

If you've built a Laravel project and need a live demo link — for a portfolio, a client presentation, or just to share with friends — spinning up a VPS just to host a demo feels like overkill.

InfinityFree gives you:

  • 🌐 A free subdomain (yourapp.great-site.net or .epizy.com)
  • 🗄️ A free MySQL database
  • ☁️ PHP hosting

All for $0.

The catch? It's not a typical shared host. There are real restrictions that break a standard Laravel deployment out of the box. This post documents exactly what breaks and how to fix every single one of them — based on a real deployment I did for a Laravel social media app.


⚠️ Know the Limitations First

Before you start, understand what you're working with:

Feature Available?
Free subdomain ✅ Yes
Free MySQL database ✅ Yes
PHP support ✅ Yes
File Manager (browser-based) ✅ Yes
SSH access ❌ No
php artisan commands ❌ No
Symlinks (storage:link) ❌ No
open_basedir restriction ❌ PHP only reads inside htdocs/
Composer on server ❌ No

🔴 The open_basedir restriction is the biggest gotcha. PHP will refuse to read any file outside of htdocs/ — which completely breaks Laravel's default folder structure.


Step 1 — Prepare Your Project Locally

Set your .env for production

APP_NAME=YourApp
APP_ENV=production
APP_KEY=base64:YOUR_32_CHAR_KEY_HERE==
APP_DEBUG=true   # temporarily true to see errors
APP_URL=http://yourapp.great-site.net

DB_HOST=sql123.epizy.com   # from your cPanel
DB_DATABASE=epiz_xxxxx_dbname
DB_USERNAME=epiz_xxxxx_user
DB_PASSWORD=yourpassword
Enter fullscreen mode Exit fullscreen mode

💡 You can't run php artisan key:generate on InfinityFree. Generate your APP_KEY locally and paste it in. It must start with base64:.

Package your files into two ZIPs

The vendor/ folder is typically 30–50MB which exceeds the File Manager upload limit. Split it:

# ZIP 1 — everything except vendor/
zip -r project.zip . --exclude="vendor/*" --exclude=".git/*"

# ZIP 2 — vendor/ folder only
zip -r vendor.zip vendor/
Enter fullscreen mode Exit fullscreen mode

Step 2 — Upload via File Manager

FTP may not connect reliably on InfinityFree's free tier. Use the built-in File Manager in your cPanel instead:

  1. Log in to InfinityFree → open File Manager
  2. Navigate to htdocs/
  3. Upload project.zip → right-click → Extract
  4. Upload vendor.zip → extract into the same folder
  5. Upload your .env file into the project root

✅ Everything — and I mean everything — must be inside htdocs/. Due to open_basedir, PHP cannot access any path above it.

Your final directory structure should look like this:

htdocs/
├── index.php        ← moved from public/
├── .htaccess        ← moved from public/
├── storage/
│   └── avatars/     ← manually created for uploads
├── app/
├── bootstrap/
├── config/
├── database/
├── resources/
├── routes/
├── vendor/
├── .env
└── ...
Enter fullscreen mode Exit fullscreen mode

Step 3 — Fix index.php

Laravel's default public/index.php references ../vendor and ../bootstrap — paths that go outside htdocs/. Since everything is now flat inside htdocs/, you need to remove the ../.

Here's the full corrected index.php:

<?php

// Temporary — remove once everything works
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

define('LARAVEL_START', microtime(true));

// ✅ No more ../ — everything is in htdocs/
require __DIR__.'/vendor/autoload.php';

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

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);
Enter fullscreen mode Exit fullscreen mode

The only change from the default: __DIR__.'/../vendor'__DIR__.'/vendor' (same for bootstrap).


Step 4 — Fix File Uploads (No storage:link)

php artisan storage:link creates a symlink from public/storage to storage/app/public. Symlinks don't work on InfinityFree.

The fix is to bypass Laravel's storage system for uploads and write directly to the web-accessible folder using $_SERVER['DOCUMENT_ROOT'].

// ❌ Default Laravel — breaks on InfinityFree
$attributes['avatar'] = request('avatar')->store('avatars', 'public');

// ✅ InfinityFree-compatible
if (request('avatar')) {
    $file     = request('avatar');
    $filename = time().'.'.$file->getClientOriginalExtension();
    $dest     = $_SERVER['DOCUMENT_ROOT'].'/storage/avatars';

    $file->move($dest, $filename);
    $attributes['avatar'] = 'avatars/' . $filename;
}
Enter fullscreen mode Exit fullscreen mode

Files saved this way are immediately accessible at:

yourapp.great-site.net/storage/avatars/filename.jpg
Enter fullscreen mode Exit fullscreen mode

✅ Make sure the htdocs/storage/avatars/ folder exists before uploading. Create it manually in File Manager.


Step 5 — Set Up the Database

Since there's no SSH, you can't run php artisan migrate. Export your schema locally and import it via phpMyAdmin:

# Export locally
mysqldump -u root -p your_local_db --no-data > schema.sql
Enter fullscreen mode Exit fullscreen mode

Then in InfinityFree cPanel:

  1. Go to MySQL Databases → create a database and user
  2. Open phpMyAdmin
  3. Select your new database → click Import → upload your .sql file

Errors You'll Hit & How to Fix Them

Error Cause Fix
403 Forbidden No index.php found in htdocs/ Move public/ contents into htdocs/
HTTP 500 Missing APP_KEY in .env Set APP_KEY manually starting with base64:
open_basedir restriction Files placed outside htdocs/ Move everything inside htdocs/, fix index.php paths
Images not loading storage:link not supported Use DOCUMENT_ROOT to write uploads directly to htdocs/storage/

✅ Deployment Checklist

Before going live, run through this:

[ ] APP_KEY set in .env (starts with base64:...)
[ ] All files inside htdocs/ — nothing outside
[ ] index.php uses __DIR__.'/vendor' not __DIR__.'/../vendor'
[ ] .htaccess moved from public/ to htdocs/
[ ] vendor/ folder uploaded and extracted
[ ] Database schema imported via phpMyAdmin
[ ] htdocs/storage/avatars/ folder created manually
[ ] File upload controller uses $_SERVER['DOCUMENT_ROOT']
[ ] APP_DEBUG set to false when done ✅
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

InfinityFree is not for production. There's no SSH, no queue workers, no scheduler, and performance is limited. But for demo projects, portfolios, and proof-of-concept apps it does exactly what it promises — gets your Laravel app live with a real URL, a real database, and zero cost.

If you outgrow it, the same codebase deploys cleanly to any proper VPS — just reverse the index.php paths and re-run php artisan storage:link.


Built and deployed a Laravel project on InfinityFree? Drop your experience in the comments — especially if you hit an error not covered here! 👇

Top comments (0)