Laravel Hosted in Subdirectory

Viewed 179

A client has requested a website built and now that it has been built, they've requested it be hosted alongside their existing website but in a subdirectory (example.com/example/path).

What I'm dealing with now is figuring out the required apache rules to host this correctly. I've uploaded the entire project structure to that directory. Within the public directory (/example/path/public) I have the following .htaccess file (henceforth I'll refer to this as the Laravel .htaccess):

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On
    RewriteBase /example/path

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]


    # Serve Cached Page If Available...
    RewriteCond %{REQUEST_URI} ^/?$
    RewriteCond %{DOCUMENT_ROOT}/page-cache/pc__index__pc.html -f
    RewriteRule .? page-cache/pc__index__pc.html [L]
    RewriteCond %{DOCUMENT_ROOT}/page-cache%{REQUEST_URI}.html -f
    RewriteRule . page-cache%{REQUEST_URI}.html [L]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

<FilesMatch ".(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot|otf)$">
    Header set Cache-Control "max-age=2628000, public"
</FilesMatch>
<FilesMatch ".(css|js)$">
    Header set Cache-Control "max-age=86400, public"
</FilesMatch>

I have added the RewriteBase line based on me trying to find a solution to this.

Within the base .htaccess file (/example/path/.htaccess), I have the following:

<IfModule mod_alias.c>
    Alias /example/path /home/www/<user>/html/example/path
    <Directory "/home/www/<user>/html/example/path">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
</IfModule>

The problem is however that this returns an internal server error. I've tried other potential solutions that don't use Alias that instead return 40X errors.

I need to be able to have the Laravel site fully working when a user visits example.com/example/path. I've tried numerous solutions over the past 90 minutes and none have worked.

What is the correct solution to my situation?

3 Answers

In public folder we have hosted 8 platforms and each platform's root directory we have this .htaccess configuration. hope this helps you.

<ifmodule mod_rewrite.c>
 
    <ifmodule mod_negotiation.c>
        Options -MultiViews
    </ifmodule>
     
    RewriteEngine On
     
    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ ^$1 [N]
 
    RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
    RewriteRule ^(.*)$ public/$1 
 
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ server.php
 
</ifmodule>

I did this recently too. My client had their Wordpress set to resolve at as the Document root (/var/www/html), but they also wanted their Laravel app "installed" in a subfolder of Wordpress and named "hq"

This however would be a security problem, because we only want Laravel's Public folder exposed, and not the application files. To solve this problem, I used the power of symbolic links!

The Laravel app was placed below the Document root at:

/var/www/laravel 

I then exposed Laravel's public folder in the DocumentRoot with the command "ln -s symlinkLocation symbolic-link-name"

ln -s /var/www/laravel/public /var/www/html/hq

In the above line, you can see that "hq" is not an actual folder, but instead a symlink to /var/www/laravel/public

(which is where Laravel's index.php entry point is, the css, js etc) enter image description here

Here is what the symbolic link looks like: enter image description here

I also made a symbolic link to the storage folder:

ln -s /var/www/laravel/public/ /var/www/laravel/storage/app/public 

Which accomplishes what "php artisan storage:link" accomplishes.

For reference, here is what my laravel .htaccess looks like:

The .htaccess in /var/www/laravel/public/.htaccess was

    <IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Hope this helps

create a htaccess file in root directory of project

and add the following lines :

#disable directory browsing
Options -Indexes
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]

#PROTECT ENV FILE
<Files .env>
order allow,deny
Deny from all
</Files>

#PROTECT htaccess FILE
<Files .htaccess>
order allow,deny
Deny from all
</Files>
Related