For new Laravel users, it’s often difficult to setup server and domain properly, especially with /public folder. This article will explain and try to help.


Why /public is needed at all?

By default, web-server is loading index.php file, right? So why Laravel framework couldn’t just have that index file in main folder? Why /public?

The answer is security. Folder name explains it all – it’s the only folder that would be publicly accessible from the browser. So anything you put in /public, like /public/css, /public/js or /public/images/products – those will be accessible just by typing URL in the browser.

At the same time, it’s protecting all the other folders which are one level above.
So /app, /config, /resources folders will not be available to load from the browser, no matter what URL someone puts in.

In other words, all your application logic is hidden from browser, and you allow only /public folder to be accessible.


How to configure /public folder?

Another mistake from new Laravel developers I see, is that they load URL like this: http://localhost/project1/public – so public is a part of the URL. It is possible and may even work locally, but can you imagine someone typing that as part of real URL?

Can you imagine writing facebook.com/public instead of facebook.com in the browser?

So, our goal is that your domain would automatically load /public folder somehow. And that depends on web-server you are using.

Most likely you are using Apache or Nginx.
Even if you are using some web-server bundle like XAMPP/MAMP or virtual server like Laravel Homestead, underneath they still have one or another – Apache or Nginx.

So you need to configure domains (or they are sometimes called sites) in those web-servers.

It will also help you to work with multiple projects. So you wouldn’t just have multiple folders and load like localhost/project1 and localhost/project2, but will have project1.test and project2.test as proper domains working locally.

Whenever you’re loading domain like project1.test, it needs to be configured in Apache or Nginx configuration files.

Locations and names of those files will vary depending on your operating system.

For Apache, file name may be in sites-enabled folder, for example /etc/apache2/sites-enabled/000-default.conf or, for MAMP, it would be /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf where you need this:

<VirtualHost *:80>
    ServerAdmin povilas@laraveldaily.com
    DocumentRoot "/Applications/MAMP/htdocs/project1/public"
    ServerName project1.test
</VirtualHost>

See that /public part at the end of DocumentRoot? That’s exactly how to point your domain to that public folder.

Notice: after editing that configuration file, don’t forget to restart Apache server.


For Nginx server, configuration file will be somewhere like /etc/nginx/sites-enabled/project1.test, with this code:

server {
    listen 80;
    listen [::]:80;

    . . .

    root /var/www/html/project1/public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    . . .
}

In this case, you need to look at root variable and put /public at the end of it. Also, restart the server.


Don’t forget .env file

Another thing I see often is that people leave .env file with default values after installation, except for changing DB credentials.

What you need to set up is APP_URL variable.

In your case, it should be your domain name with full prefix http:// or https://.

APP_URL=http://project1.test

I’ve written an article about it with a bit more details – Why it’s important to change APP_URL in Laravel .env file

Other articles may be useful:

Finally, if it sounds too complicated, there are tools to help setting up servers quicker, I’m a big fan of Laravel Forge – here’s a video of how we use it for our projects.

So, that’s it.
I hope now you understand why that /public is needed and how to configure it.