Correct Laravel application directory structure for proper security

In our first tutorial about Laravel development on Ubuntu, I had recommended moving the contents of the public folder in the Laravel installation up to the Laravel “root” directory. As I’ve been working on my application and these tutorials, I’ve realized that this was a short-sighted approach in the interest of expediency for development, which will cause difficulty when we want to deploy our application later. In particular, we want to apply the principle of least privilege and, accordingly, only make the necessary files available to our users. In general, this would be the contents of the public folder of our Laravel project.

For this example, we are going to consider the common scenario where we are using shared hosting. In this situation, on the hosting provider server, we typically have a “public” directory, often named www or public_html or similar, and other folders which are “private”. We will configure our development environment similarly by putting the contents of the Laravel public folder in the Ubuntu standard Apache “public” site folder (/var/www/html) and the remainder of the Laravel application files in a folder (sub-directory) under our projects folder.

Let’s begin by assuming that we have a standard “clean” Laravel installation in ~/projects/laravel-project. By “clean”, we mean that the public folder is unchanged from the installation using composer create-project laravel/laravel laravel-project --prefer-dist. In the Terminal, run:

where username is your Linux user ID. We are simply copying the contents of the Laravel public folder to the new directory for this particular application (project) in the standard Apache “public” directory. I recommend using similar naming between the main (base) Laravel directory and the “public” directory with laravel in the name for the application directory and the “simple” name (without laravel) for the “public” directory. For example, in this case we have laravel-project and project, respectively. Also, note that we must set the ownership of the .htaccess file to the Apache account (www-data).

Next, we’ll set up a specific Apache named virtual host for this directory (/var/www/html/project), which we’ll call project.dev. Create (using sudo!) a new configuration file named /etc/apache2/sites-available/project.dev.conf and add the following to the file:

After you have made these changes, you should be able to successfully run the application by going to http://project.dev/ in the web browser. This should display the standard “You have arrived” Laravel page. It should NOT be necessary to include /index.php in the URL, since the .htaccess file in /var/www/html/project removes it.

If you have trouble, make sure that the Apache mod_rewrite extension is enabled:

sudo a2enmod rewrite
sudo service apache2 restart

Likewise, ensure that you have AllowOverall All set in your virtual host configuration (or globally via the /etc/apache2/apache.conf file in the <Directory /var/www/> section).

With these changes, you should now be able to update your Laravel application files in ~/projects/laravel-project and changes to the “public” files in /var/www/html/project should not be necessary. Each time you make a change to the application, just refresh http://project.dev/ in your browser to observe the change.

To confirm this, open the app/routes.php file and add a new route to the end of the file:

Route::get('test', function()
{
echo 'This is the "test" route!';
});

In the web browser, enter the URL http://project.dev/test (withoutindex.php or trailing slash). The browser should simply display the text This is the “test” route!.

In addition, you will need to update the debugging configuration in Aptana (or Eclipse) to reference the appropriate URL (http://project.dev/). You will probably want to create a new External Web Server Configuration and set the Base URL to http://project.dev and the Document Root to /home/username/projects/laravel-project. In your Debug Configuration, set the Initial Script to bootstrap/start.php. Likewise, you will want to uncheck (disable) URL Auto Generate and leave the URL with just the base URL of http://project.dev/.

I’m not certain where you are getting your info, but
great topic. I needs to spend a while studying more or understanding more.
Thank you for magnificent information I was on the lookout for this information for my mission.

Thanks for the feedback…
I’ve been reading a variety of resources online and just kind of practicing myself. As you can tell from the (in)frequency of posts, it takes a good bit of time to figure some of this stuff out. I want to be thorough, since most of the online tutorials and references that I find (seem to) assume a significant amount of experience.