{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreig2kxuudrxhwgim6dlj4r5gsbxp2oq5fpg6z56wedc34wputeqkru",
    "uri": "at://did:plc:qfsyszxhq5agxsg2n5zo4lno/app.bsky.feed.post/3mlo2jpddtse2"
  },
  "path": "/t/how-to-install-a-laravel-site-on-infinityfree/118578#post_1",
  "publishedAt": "2026-05-12T14:50:36.000Z",
  "site": "https://forum.infinityfree.com",
  "tags": [
    "premium hosting"
  ],
  "textContent": "Laravel is one of the most popular PHP frameworks, but it was not designed with regular shared web hosting in mind. Some parts of Laravel work out of the box on InfinityFree, some need a bit of configuration, and some features cannot be used at all. This article walks you through what to do, what to watch out for, and what you’ll need to work around.\n\n## The document root problem\n\nWhen you install Laravel, you get a folder structure that looks roughly like this:\n\n\n    my-laravel-app/\n    ├── app/\n    ├── bootstrap/\n    ├── config/\n    ├── database/\n    ├── public/\n    │   └── index.php\n    ├── resources/\n    ├── routes/\n    ├── storage/\n    ├── vendor/\n    └── .env\n\n\nThe `public` folder is meant to be the web root. Everything outside of it is meant to be private: your `.env` file with database credentials, your application code, your logs, your dependencies, none of it should be reachable from the web. Only the `public` folder, which contains the front controller (`index.php`) and your CSS, JavaScript, and uploaded files, is supposed to be web-accessible.\n\nMost web servers let you configure which folder is served as the web root, and Laravel expects you to point yours at `public`. On InfinityFree, the web root is always the `htdocs` folder of your hosting account, and there is no way to change that. If you upload your Laravel application into `htdocs` as-is, your application code, configuration, and database credentials become directly accessible over the web.\n\n## The solution\n\nYou can fix this with two `.htaccess` rules. The idea is simple: upload your entire Laravel application into `htdocs`, then use rewrite rules to make every request behave as if it came in through the `public` folder.\n\n### Step 1: Prepare and upload your Laravel application\n\nBefore uploading, you need to prepare your project locally because some things cannot be done on the server:\n\n  * **Install dependencies.** Run `composer install --no-dev` locally so the `vendor` folder is populated with only the dependencies needed in production. This folder is usually excluded from version control, so it won’t be there if you cloned from Git. The `--no-dev` flag skips development tools like PHPUnit and debugging packages, which keeps the file count down and avoids uploading code that has no purpose on the server.\n  * **Compile your frontend assets.** If your project uses Vite or Mix, run `npm install` and `npm run build` locally to compile your CSS and JavaScript. You cannot run npm commands on InfinityFree, so this must happen on your own machine.\n  * **Do not upload`node_modules`.** This folder is only needed during asset compilation and serves no purpose on the server. It contains tens of thousands of files and will waste a significant chunk of your inode quota.\n\n\n\nOnce prepared, upload your complete Laravel project into the `htdocs` folder of your hosting account. After uploading, your file structure should look like this:\n\n\n    htdocs/\n    ├── app/\n    ├── bootstrap/\n    ├── config/\n    ├── public/\n    │   ├── index.php\n    │   └── .htaccess\n    ├── storage/\n    ├── vendor/\n    └── .env\n\n\nMake sure your `.env` file is uploaded too. FTP clients sometimes hide dotfiles by default, so check your client’s settings if you don’t see it. You will also need to create one more file, `.htaccess` in the `htdocs` folder, which is covered in the next step.\n\n### Step 2: Create an .htaccess file in htdocs\n\nCreate a file called `.htaccess` directly in the `htdocs` folder (not inside `public`) with this content:\n\napache\n\n\n    RewriteEngine On\n    RewriteRule (.*) /public/$1 [L]\n\n\nThat is the entire file. This rule rewrites every incoming request to go through the `public` folder. A request for `/` becomes `/public/`, a request for `/about` becomes `/public/about`, and so on.\n\nThis works as a security measure too. Any request for a sensitive file like `/.env` or `/storage/logs/laravel.log` will be rewritten to `/public/.env` or `/public/storage/logs/laravel.log`, which do not exist, so visitors get a 404 instead of the actual file.\n\n> **Note:** Laravel ships with its own `.htaccess` file inside the `public` folder, which handles routing requests to `index.php`. Do not modify or delete it. The two files work together: the one in `htdocs` redirects requests into `public`, and the one in `public` hands them off to Laravel’s front controller. If for some reason the `public/.htaccess` file is missing, you can recreate it with Laravel’s standard content:\n>\n>\n>     <IfModule mod_rewrite.c>\n>        <IfModule mod_negotiation.c>\n>            Options -MultiViews -Indexes\n>        </IfModule>\n>\n>        RewriteEngine On\n>\n>        # Handle X-XSRF-Token Header\n>        RewriteCond %{HTTP:x-xsrf-token} .\n>        RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}]\n>\n>        # Redirect Trailing Slashes If Not A Folder...\n>        RewriteCond %{REQUEST_FILENAME} !-d\n>        RewriteCond %{REQUEST_URI} (.+)/$\n>        RewriteRule ^ %1 [L,R=301]\n>\n>        # Send Requests To Front Controller...\n>        RewriteCond %{REQUEST_FILENAME} !-d\n>        RewriteCond %{REQUEST_FILENAME} !-f\n>        RewriteRule ^ index.php [L]\n>     </IfModule>\n>\n\n## Handling file storage\n\nIf your application uses Laravel’s public disk to store user uploaded files (avatars, attachments, and so on), there is one more thing to set up. Laravel normally expects you to run `php artisan storage:link`, which creates a symlink from `public/storage` to `storage/app/public`. InfinityFree does not support symlinks, so you need an alternative.\n\nThe fix is another rewrite rule. Open the `.htaccess` file you created in `htdocs` and add a second rule before the catch-all:\n\n\n    RewriteEngine On\n    RewriteRule ^storage/(.*)$ /storage/app/public/$1 [L]\n    RewriteRule (.*) /public/$1 [L]\n\n\nThe new rule maps any request for `/storage/something.jpg` to the actual file in `storage/app/public/something.jpg`. Order matters here: the storage rule must come before the catch-all, otherwise the request gets sent to `/public/storage/...` first and never reaches the right file.\n\nIf your application does not use file uploads or the public disk, you can skip this step.\n\n## Configuration tips\n\nA few Laravel settings to check before going live:\n\n  * Set `APP_ENV=production` and `APP_DEBUG=false` in your `.env` file. Leaving debug mode on in production exposes sensitive information whenever an error occurs.\n  * Set `APP_URL` to your actual domain, including `https://` if you have SSL enabled (which you should).\n  * Set `SESSION_DRIVER=file` and `CACHE_DRIVER=file`, since InfinityFree does not provide Redis or Memcached.\n  * Set `QUEUE_CONNECTION=sync` if your application uses queues. InfinityFree does not support background workers, so jobs need to run synchronously during the request.\n  * For email, use `MAIL_MAILER=smtp` with an external SMTP provider. InfinityFree does not provide an email service, so you’ll need to bring your own (Gmail, Mailgun, Brevo, and similar services all work).\n\n\n\nFor the database, first create a MySQL database from your members area under MySQL Databases. Once created, use the credentials shown there in your `.env` file. The database host is not `localhost`, it is a specific hostname shown in the same section.\n\n## Things that won’t work\n\nLaravel is a flexible framework, but free hosting does have its limits. A few features you should know about upfront:\n\n  * **Scheduled tasks.** InfinityFree does not provide cron jobs or any other way to run scheduled tasks. Anything that relies on `php artisan schedule:run` cannot run on free hosting. If your application depends on scheduled tasks, premium hosting is the only real option.\n  * **Queue workers.** InfinityFree does not allow long running background processes, so `php artisan queue:work` cannot run. You can still use queueable jobs, but only with the `sync` queue driver, which processes jobs immediately during the request that dispatches them. This works for simple cases but defeats the purpose of queues for slow operations.\n  * **WebSockets and real-time features.** Laravel Echo, Reverb, and similar real-time features require a separate WebSocket server, which is not supported.\n  * **Artisan commands.** You cannot run `php artisan` from a terminal because shell access is not available. This has practical consequences for setting up your database, since `php artisan migrate` and `php artisan db:seed` are the usual ways to populate it. Instead, you can either export your local database as a SQL dump and import it through phpMyAdmin, or use `php artisan schema:dump` locally to generate a SQL file and import that. After the initial setup, you’ll need to repeat this process for any future schema changes.\n  * **Large applications.** Free hosting comes with strict limits on CPU, memory, and inodes (file count). Laravel applications, especially with a `vendor` folder containing tens of thousands of files, can hit the inode limit quickly. If your application is complex or has many dependencies, premium hosting is the more practical option.\n\n\n\n## Common problems\n\n### Stale cache after uploading\n\nLaravel caches configuration, routes, and views in the `bootstrap/cache` and `storage/framework` folders. When you upload your project, these folders may contain cache files from your local environment that reference paths or settings that don’t match the server. The result is confusing errors that don’t seem to match your actual code.\n\nIf something is misbehaving and you can’t figure out why, delete the contents of `bootstrap/cache` (but keep the folder itself, and keep the `.gitignore` file inside if present). Laravel will regenerate the cache on the next request. The same applies to compiled views in `storage/framework/views`.\n\nAs a habit, run `php artisan optimize:clear` locally before uploading, or simply don’t upload the contents of these cache folders in the first place.\n\n### Missing files after upload\n\nInfinityFree silently rejects PHP files larger than 1 MB. The file appears to upload successfully, but when you check the server, it is simply not there. This can cause confusing errors where Laravel complains about classes that should exist but suddenly don’t.\n\nThe usual culprit is the optimized Composer autoloader. Laravel’s `composer.json` enables autoloader optimization by default, which generates a class map file at `vendor/composer/autoload_classmap.php`. On larger projects, this file can easily exceed 1 MB.\n\nIf files seem to be missing after upload, regenerate the autoloader without optimization before uploading:\n\n\n    composer dump-autoload --no-dev --optimize=false\n\n\nThis produces a smaller autoloader at the cost of slightly slower class loading. For most Laravel sites on free hosting, the performance difference is not noticeable.\n\n## Summary\n\nTo setup Laravel on InfinityFree:\n\n  1. Run `composer install --no-dev` and compile your frontend assets locally. Don’t upload `node_modules`.\n  2. Upload your entire Laravel project into `htdocs`.\n  3. Create an `.htaccess` file in `htdocs` with rewrite rules to redirect requests into `public` and, if needed, map `/storage/` to `storage/app/public/`.\n  4. Leave the `public/.htaccess` file as Laravel ships it.\n  5. Configure your `.env` for production with file based sessions and cache.\n  6. Import your database schema through phpMyAdmin, since artisan commands cannot be run on the server.\n\n\n\nIf you run into issues, create a support topic on the forum with details about what you tried and any error messages you see.",
  "title": "How to install a Laravel site on InfinityFree"
}