Laravel | Shared hosting routes not working properly - apache

I am trying to deploy my Laravel project on a shared host(godaddy) and so far I have only partially succeeded.
Steps I followed:
Create a subdomain abc.xyz.com , root -> public_html/finance/.
Upload my laravel project to a folder which is at same level as that of public_html
softlink the public directory of my project to public_html/finance/
I found that going to abc.xyz.com didn't work but abc.xyz.com/public did so I set up a redirect which redirects abc.xyz.com to abc.xyz.com
making Storage accessible for web.
dumpautoload, caching config and routes.
migarting databases.
Now I can successfully login which takes me to abc.xyz.com/public but my all other routes which does not have /public do not work.
For example:
abc.xyz.com/public - works
abc.xyz.com/home - doesn't work
I noticed that if I manually add /public to all routes they work!. so abc.xyz.com/public/home works.
my .htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
So how can append /public like abc.xyz.com/public to all the routes?
I am not very good at modifying .htaccess but I tried some solutions from online and they did not work.

Excerpted from Deploy Laravel 5 App on Shared Hosting on Linux Server. The original authors were Donkarnash, PassionInfinite, Pete Houston and Kyslik. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive. Reference topic ID: 2410.
By default Laravel project's public folder exposes the content of the app which can be requested from anywhere by anyone, the rest of the app code is invisible or inaccessible to anyone without proper permissions.
After developing the application on your development machine, it needs to be pushed to a production server so that it can be accessed through the internet from anywhere - right?
For most apps/websites the first choice is to use shared hosting package from hosting service providers like GoDaddy, HostGator etc. mainly due to low cost.
note: you may ask your provider to manually change document_root, so all you have to do is upload your Laravel application to server (via FTP), request change of root to {app}/public and you should be good.
Such shared hosting packages, however do have limitations in terms of terminal access and file permissions. By default one has to upload their app/code to the public_html folder on their shared hosting account.
So if you want to upload a Laravel project to a shared hosting account how would you go about it? Should you upload the entire app (folder) to the public_html folder on your shared hosting account? - Certainly NO
Because everything in the public_html folder is accessible "publically i.e. by anyone" which would be a big security risk.
Steps to upload a project to shared hosting account - the Laravel way
Step 1
Create a folder called laravel (or anything you like) on the same level as the public_html folder.
Eg:
/
|--var
|---www
|----laravel //create this folder in your shared hosting account
|----public_html
|----log
Step 2
Copy every thing except the public folder from your laravel project (on development machine) in the laravel folder (on server host - shared hosting account).
You can use:
- C-panel : which would be the slowest option
- FTP Client: like FileZilla to connect to you shared hosting account and transfer your files and folders through FTP upload
- Map Network Drive: you can also create a mapped network drive on your development machine to connect to your shared hosting account's root folder using "ftp://your-domain-name" as the network address.
Step 3
Open the public folder of your laravel project (on development machine), copy everything and paste in the public_html folder (on server host - shared hosting account).
Step 4
Now open the index.php file in the public_html folder on the shared hosting account (in cpanel editor or any other connected editor) and:
Change:
require __DIR__.'/../bootstrap/autoload.php';
To:
require __DIR__.'/../laravel/bootstrap/autoload.php';
And Change:
$app = require_once __DIR__.'/../bootstrap/app.php';
To:
$app = require_once __DIR__.'/../laravel/bootstrap/app.php';
Save and close.
Step 5
Now go to the laravel folder (on shared hosting account -server) and open server.php file
Change
require_once __DIR__.'/public/index.php';
To:
require_once __DIR__.'../public_html/index.php';
Save and close.
Step 6
Set file permissions for the laravel/storage folder (recursively) and all files, sub-folders and file within them on shared hosting account - server to 777.
Note: Be careful with the file permissions in linux, they are like double edged sword, if not used correctly, they may make your app vulnerable to attacks. For understanding Linux file permissions you can read https://www.linux.com/learn/tutorials/309527-understanding-linux-file-permissions
Step 7
As .env file of local/development server is Ignored by git and it should be ignored as it has all the environment variables including the APP_KEY and it should not be exposed to public by pushing it into the repositories'. You can also see that .gitignore file has .env mentioned thus it will not upload it to repositories.
After following all the above steps make a .env file in the laravel folder and add all the environment variable which you have used from the local/development server's .env file to the .env file of production server.
Even there are configuration files like app.php, database.php in config folder of laravel application which defines this variables as by default in second parameter of env() but don't hard-code the values in these files as it will affect the configuration files of the users who pulls your repository. So it is recommended to create .env file manually!
Also laravel gives .env-example file that you can use as a reference.
That's it.
Now when you visit the url which you configured as the domain with your server, your laravel app should work just as it worked on your localhost - development machine, while still the application code is safe and not accessible by anyone without proper file permissions.

You can probably move your public/.htaccess and public/index.php to the root files of your laravel project.

You need to change the document root for you website to be the public folder of your application i.e.
public_html/finance/.
should be:
public_html/finance/public
https://laravel.com/docs/5.4/installation#configuration
Hope this helps!

The problem is that you have placed the entire project in the public directory - public_html, haven't you? This is a bad practice (security).
Your domain (abc.xyz.com) points to your application root directory, should go to the app/public dir.

Update Solution: require DIR.'/../bootstrap/autoload.php';
Is now: require DIR.'/../vendor/autoload.php';
So Change To require __DIR__.'/../laravel/vendor/autoload.php';

In addition to pointing to the correct files and folders, add the below .htaccess file. Credit - Kylevorster
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

Related

Specify to load index.html file for every request in apache config file

I have a React application hosted on my server and I need to always load index.html file for every request users make.
Let's say that I have a website that has the address xyz.com, and the root directory contains the React build files, including this index.html file. There are many routes that users can specify to access to certain parts of the website, for example to register on the website they can access xyz.com/register. So, what I want to accomplish is instruct server to always serve this index.html every time users access my site, even though they are visiting different routes of the website.
So I'm assuming that this is something that I can set up in the .conf file for the website, and if it is, can you please let me know how I can achieve it?
You can use the below rewrite rule.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.html$
RewriteRule .* /index.html [L,R=302]

Remove /public from URL in a subfolder

I'm building a Laravel application, and it will be in a subfolder of a current project. I'm trying to get rid of the /public in the URL, so that the users can view the project at this URL :
www.domain.com/project
instead of the default ...
www.domain.com/project/public
I did some digging on StackOverflow and the Laracasts forum, and I tried this, in a .htaccess file at the root of my project :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
However, my routes doesn't work anymore when I do this. Even the default route for / stopped working.
A lot of answers mention that the best way is to change the root in the Apache config, so that it serves the files from /public instead of at the root of the directory.
The problem is that this in a subfolder of a main project, how can I make it so that only this project is affected? The website at www.domain.com works fine and does not have a /public in the URL.
There are a couple options. I don't think you want to try fixing this at the htaccess level with mod rewrites (or anything like that)
One option is to create another virtual host that listens on an abitrary port (eg, 8080). Then set the document root for this virtual host to .../public/
Another option, you can spoof the dns in your /etc/hosts or Windows hosts file, and set up a dev.domain.com virtual host.
•Go to mainproject/public>>
a. .htacess
b. favicon.ico
c. index.php
d. robots.txt
e. web.config
1.cut these 5 files from public folder,and then paste on the main project folder that’s means out side of public folder… mainproject/files
2.Next after paste ,open index.php ,modify
•require __DIR__.'/…/bootstrap/autoload.php'; to
•require __DIR__.'/bootstrap/autoload.php';
modify
- $app = require_once DIR.'/../bootstrap/app.php'; to
- $app = require_once DIR.'/bootstrap/app.php';

htaccess redirect URI to parent directory

I have a website hosted in /var/www/thesite (apache server), it's a Symfony2 website so inside this folder I have a web folder to which my virtual host is pointing.
So my virtualhost is www.mysite.com -> /var/www/thesite/web
In this web folder I have a .htaccess to format URL nicely.
Now, I've added an API in /var/www/thesite/api, the API is implemented using Silex.
I want to redirect all request http://www.mysite.com/api to this new framework.
So I've added in /var/www/thesite/web/.htaccess
RewriteCond %{REQUEST_URI} ^/api
RewriteRule ^api(.*)$ ../api/web/index.php [NC,QSA,L]
But I get:
Bad Request
Your browser sent a request that this server could not understand.
I'm not sure if I can access parent folder in the .htaccess. I don't want to change my virtualhost target directory to avoid security breach.
How can I solve this issue?
You can't route a request to outside of the site's document root, which is /var/www/thesite/web. So you can't access /var/www/thesite/ or /var/www/thesite/api from inside the /var/www/thesite/web directory. The 400 Bad request is because of the ../api/ bit of your rule's target.
Something you can try doing is just using php to include/require the api's index.php:
RewriteRule ^api/(.*)$ /index_api.php [L]
And in the index_api.php you can include or require the "../api/web/index.php" file.

CodeIgniter include js,css files from application returns 403 forbidden

I am having a problem loading a javascript or css or any other file from inside the application/modules directory.
I am using MAMP and CodeIgniter with HMVC and trying to have a js and css folders inside a module folder. Then when I am calling the controller methods I am also loading the asset files.
I have other sites that are working in that way. The structures are the same and the CodeIgniter versions are the same. Basically I have copied the previous website and started from there.
But it always returns 403 forbidden.
What I did but still nothing changes:
the whole site directory is writable and readable.
I can create and read new files from PHP to that dir
I have htaccess file which I tried to remove or change
Reinstalled MAMP
Tried to open a simple html file
The MAMP user and group has full access to the dir
I tried to run the website on another server
The apache log says "[Tue May 22 17:24:30 2012] [error] [client 127.0.0.1] client denied by server configuration"
Here is the .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
At the same time everything is fine with the other site.
I have spent many hours so far and I am stuck.
Any thoughts or suggestions are appreciated.
Thanks,
CodeIgniter comes with a .htaccess in the /application directory which contains
Deny from all
You'll need to remove this file or change it's ruleset to access js/css files etc from anywhere inside application/*
It is however largely inadvisable to allow access entirely to the application, it's perhaps best to modify this .htaccess file to allow access to application/modules/*/css|js/

How can I accomplish this type of mod_rewrite?

I would like to setup a staging and production environment on one shared server. So, optimally, I would like to be able to create a structure like the following on the server:
/stage/
/lib/
/web/
/js/
/css/
index.php
...
/production/
/lib/
/web/
/js/
/css/
index.php
...
However, although I am able to change the document root of an added subdomain or addon domain, I am unable to change the document root of the primary domain. So, I am stuck with the document root being /public_html/.
I would like the staging environment to be accessible through stage.domain.com (pointing to /stage/web/), and every other subdomain, *.domain.com or domain.com, route to the production environment (pointing to /production/web/).
With that in mind, I believe I need a robust mod_rewrite script to do the job (.htaccess level). Since, I am a novice at mod_rewrite, does someone know how to write a script that will transparently route the requests appropriately?
or
Is there a better way to handle these two environments on a shared server?
If you can't change the document root of main domain. Can you create a symlink in public_html name production folder to /web/production. Enable symlinks.
RewriteCond {REQUEST_FILENAME} !-f
RewrireRule ^(.*)$ production/$1 [QSA,L]