Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

JessycaFrederick's avatar

Need the basics of moving to production, please

Quick background: I have my first Laravel project locally. I have the files in a private repo on Github. I have successfully tested my SSH connection to Github and am able to deploy --bare repos, etc. I expect to make use of GitHub workflows. I've been mucking around with several different recommended processes (that are all very similar) but I remain lost regarding a few details.

My goal:

  1. Push files to the repo on Github
  2. Automagically push project to a staging server at the same time
  3. Use CLI to manually push files from staging to production after I've tested

My questions:

  1. Is the "production" location my /home/public_html/ folder? or is it /home/public_html/public? Or is it a part of my remote (my server) repo and I'm supposed to use some other means of linking my /home/public_html folder to that repo?

  2. When do I turn the project files into a public build? Does that happen between local and staging? Or between staging and production?

Please and thank you.

0 likes
11 replies
JessycaFrederick's avatar

@sr57 This is the best explanation I've seen yet. Thank you for sharing it!

Where I'm confused with "public" is that Laravel has a directory called "public" and my server path is /home/public_html. Inside public_html is my old app (in a directory called app, it's codeigniter, not Laravel) and miscellaneous files that the domain uses but aren't a part of the application (sitemap.xml, .htaccess, etc.). So just to be clear, when I set up "post-receive file in the production repo" I will be sending all files to /home/public_html and it will overwrite whatever it needs to, ignoring what it doesn't? Or does it wipe the directory and dump the entire contents of the staging repo into it?

On staging I expect others to be able to view/interact with the content as if it was the real site. Staging will be password-protected.

Thank you!

JessycaFrederick's avatar

@sr57 I appreciate you pointing this out and I see why you did. I have been reading/learning about this. I'm still confused, but in a different way.

What I understand is that the directories that are not /public (i.e. /app, /config) etc. need to be outside the document root (/path/to/public_html). Currently I have directories like /bin and /mail, etc. that are on my server but not in my document root (presumably this is what you meant by <(virtual)web server root>?).

Do the Laravel directories for /app and /config, etc. go in the <(virtual)web server root>?

I read that Laravel /public should never be in a subdirectory of the document root. If I have subdomains with their own/different Laravel apps, do they all share the same docs in the <(virtual)web server root> but have their own public files? For example, dev.mydomain.com points to a directory at /path/to/document_root/dev

kokoshneta's avatar
Level 27

@JessycaFrederick The easiest way to define what your document root directory is this: if you go to yourdomain.com, the file you see will be the first matched index file in the document root folder (that is, index.htm, index.php, default.asp, etc.). The document root is the topmost directory that the server exposes to the outside world – anything not inside that directory cannot be accessed from a browser. In your case, it sounds like your document root is /home/public_html.

Now the crux: The server’s document root folder should be Laravel’s public-facing folder, so the Laravel project as a whole should be uploaded into the parent folder of the document root, i.e., /home. Depending on what type of hosting and server access you have, there are two basic ways to then make sure that the server’s document root and Laravel’s public-facing folder refer to the same location:

  • Best way (if you have admin access to your server and can change its settings; won’t work on most regular shared hosting servers): Change the server document root to /home/public and then upload your Laravel project to /home (the old /home/public_html will still be there, but will no longer be accessible from a browser, since it’ll be outside the document root). This requires permission to be able to change your server configuration and likely won’t work if you’re on regular shared hosting.
  • Alternative (if you don’t have admin rights on the server): Upload your Laravel project to /home and then move all the files inside the /home/public folder into /home/public_html (note that this may overwrite files from your previous project – you should get those out of the way first, for instance by putting them into a subdirectory). Then do as described in this StackExchange answer to make Laravel recognise that every time something refers to the Laravel ‘public’ folder, it should look in /home/public_html.

The first of these is best because it requires no further configuration: once you change the document root in your server settings, you’re good to go.

The second way is more of a bother, because your development and production environments will now be different – and so will your app service provider. In order to avoid that, you should also rename the /public folder to /public_html in your local development environment, make the same change to the AppServiceProvider as above, and then edit the server settings on your local server to use /path/to/project/public_html as the document root.

If you have subdomains with separate Laravel apps, these are treated completely separately. They will each have their own document root folders, which is where the other Laravel apps should be uploaded into. So you will have a structure like this:

/home
   | // Contains your main Laravel application
   |---/public(_html)
   |   | // Main document root; contains your main application’s index.php, etc.
   |---/sub1
   |   | // Contains the Laravel app for sub1.example.com
   |   |---/public(_html)
   |   |   | // Document root for sub1.example.com; contains index.php, etc.
   |---/sub2
   |   | // Laravel app for sub2.example.com
   |   |---/public(_html)
   |   |   | // Document root for sub2.example.com
1 like
JessycaFrederick's avatar

@kokoshneta Thank you!

I believe you have answered the question about which directory the Laravel project should go in.

I believe I do have the kind of access you describe in "Best Way." I have a server on a dedicated IP where I control all of the the websites/accounts. I am comfortable experimenting with all of this on the destination domain because I'm not using it for anything right now.

What you show for the subdomains is what I was expecting to do. Thank you for confirming! It seems @sr57 thinks this is no longer legit Laravel and possibly insecure. I will investigate or await an answer here.

Again, thank you so much for taking the time!

Snapey's avatar

@kokoshneta There is another way which I have used on some cpanel systems, and that is to delete the public_html folder then recreate it as a symlink to the project's public folder instead.

This way, the web server sees no change and the Laravel project sees no change.

1 like
kokoshneta's avatar

@JessycaFrederick No, what @sr57 is saying is no longer a Laravel app is if you hack the system to force Laravel to use a different folder than the document root as its public-facing folder. You can absolutely have other subdomains – as long as they’re not located inside your document root (which they should NEVER be – note how in the directory listing above, public_html, sub1 and sub2 are all sibling directories; the latter two must never be children of the first).

1 like
kokoshneta's avatar

@Snapey Ah yes – I actually meant to add that as a third option, but then couldn’t remember what the third option I’d meant to add was! That is better than moving and renaming, since it won’t affect the local developent environment.

(You could also get around that bit by conditionally binding the public_html folder only if in production mode. But simply changing the server’s document root is still preferable, I think.)

1 like
JessycaFrederick's avatar

@Snapey This is what I ended up doing. It worked like a charm except the cPanel cron job didn't run as expected, so I manually changed the group. Thanks!

sr57's avatar

<(virtual)web server root> is the directory where you define the (virtual) web server conf root directory (DocumentRoot for Apache)

It's the root directory of your Laravel App

https://laravel.com/docs/8.x/structure#the-root-directory

and you can read this VERY IMPORTANT LINE :

The public directory contains the index.php file, which is the entry point for ALL requests entering your application and configures autoloading.

Having other directories is possible but you have to manage to always fulfill the previous point, if not you HAVE TO SETUP your own security points that I'm sure your are not able to do since you post this thread and doing this it will no more be a Laravel app.

Please or to participate in this conversation.