Skip to content

Instantly share code, notes, and snippets.

@a-h-abid
Last active November 30, 2017 04:12
Show Gist options
  • Save a-h-abid/42cd1e4f15a6ee9274e27815a30cdeb6 to your computer and use it in GitHub Desktop.
Save a-h-abid/42cd1e4f15a6ee9274e27815a30cdeb6 to your computer and use it in GitHub Desktop.
A proper directory structure for Laravel 5 to be used in many kind of servers, VPS and Shared Hosting included. While you can set Document Root to your project, this also gives you the advantage of putting the whole project in a sub-folder / sub-directory.

Laravel 5 Structure for document root, public_html and sub-folder/sub-directory based access on VPS and Shared Hosting

Date: 2017-Nov-20

It becomes really annoying when you have to deal with these age old shared hosting servers. Yeah they might have PHP 7, but that doesn't do any justice if we can't change the Document Root to the one needed by our project.

Learning through various places guides us to only put public files in the web/public folder. Which means setting the Document Root. But many of our ugly old shared hosting sites like godaddy, hostgator etc. do not let us set this simple document root for our primary domain, yet they allow when you add sub-domains (??? confused :S). I wish we could simply change these hostings to some VPS like digitalocean, but alas, your company boss not interested to change hosting. So, yeah, dealing with this problem for ages. And I HATE IT!!

Many of us Laravel developers have somehow managed to run laravel in these shared hosting sites, but what we usually do not take into consideration is the fact that we are also exposing our app codes and most importantly, our .env file filled with secrets. So with this, I wanted to make a structure & configuration in which our laravel app will:

  • Will not change the way we develop laravel.
  • Less hassle to deploy to VPS or Shared Hosting.
  • Work on sub-folder / sub-directory for Shared Hosts (for Apache Web Server).
  • Ensure our app codes and env file is secured.

So lets see what kind of format and modifications we do to achieve this.

PS. Many of these info, guide, settings can already be found throughout internet. I compiled all of them in one place and added my own flavor to make it look & function good.

WIP..

..WIP..

Final

Here is how our final folder structure would look something similar like.

Root
|- myapp/
|  |- app/
|  |- bootstrap/
|  |- config/
|  |- database/
|  |- mobules/
|  |- resources/
|  |- routes/
|  |- storage/
|  |- vendor/
|  |- .env
|  |- .htaccess
|  |- artisan
|  |- composer.json
|  |- package.json
|  |- server.php
|  ...
|
|- public_html/
|  |- assets/
|  |- modules/
|  |- themes/
|  |- .htaccess
|  |- favicon.ico
|  |- index.php
|  |- robot.txt
|
|- .htaccess
|- index.php

There could be some incompatibility with some third party packages, mainly for the assets, so you might have to update those by modifying or extending.

<?php
namespace App\Extender\Illuminate\Foundation;
use Illuminate\Foundation\Application as LaravelApplication;
class Application extends LaravelApplication
{
/**
* Get the path to the public / web directory.
*
* @return string
*/
public function publicPath()
{
return realpath($this->basePath.'/../public_html');
}
}
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new App\Extender\Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;
<?php
return [
...
...
...
'disks' => [
'local' => [
'driver' => 'local',
'root' => realpath(base_path().'/../'),
'permissions' => [
'file' => [
'public' => 0777,
'private' => 0700,
],
'dir' => [
'public' => 0777,
'private' => 0700,
],
],
'url' => env('APP_URL'),
'visibility' => 'public',
],
...
...
...
];
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__.'/../myapp/vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../myapp/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
/public_html/hot
/public_html/storage
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Files to Ignore
# Add more files as your project needs
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|\.ttf|\.svg|\.eof|\.woff2?|robots\.txt|favicon\.ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Front Controller
# Rewrite assets, modules etc folders through public_html folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/public_html/
RewriteRule ^(assets/modules/themes)/(.*)$ public_html/$1/$2 [L,NC]
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<?php
require_once __DIR__.'/public_html/index.php';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment