Reputation: 6707
I am using the Laravel framework to create a web application. Laravel applications are accessed from index.php
in the app's public
directory.
The homepage route is defined as:
Route::get('/', 'HomeController@index');
But I can only access this from the URL https://example.com/public
.
How can I make the /public
folder as root?
Curently I've found a workaround. I can create an index.php
on the root and write a redirect code to /public
folder. So when user enters http://example.com/
, it will be redirected to http://example.com/public
automatically. But still that's ugly. I don't like to see /public
in the URL. Any suggestion?
Upvotes: 18
Views: 44117
Reputation: 51
you can use RewriteRule ^public(/.*)?$ / [R=301,L]
when URL hit domain/public then redirect 301
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect requests to /public to the root URL
RewriteRule ^public(/.*)?$ / [R=301,L]
# Rewrite all other requests to the public folder
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Upvotes: 0
Reputation: 9625
The domain name should point to the /public
folder as if it were your public_html
folder.
index.php
should be executedYou need to place an .htaccess
file in the /public
folder that contains the lines you mentioned, especially these:
# 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]
This way, every URL called under a domain name will start from your /public/index.php
, which builds up your Laravel app. Eventually, it will either run the appropriate route defined in the /routes
or return a 404 blank page if no matching route is found.
The /public
appears in the URL if your domain name points to your-project instead of your-project/public
. Therefore, you can access your starting index.php
with https://example.com/public/index.php
.
# normal directory tree
server
├── your-project
│ ├── app
│ ├── routes
│ ├── public <--- domain root
│ │ ├── index.php
│ │ └── .htaccess
│ ├── ...
If the root of your domain points to the /your-project/public
folder and you can still access its content using the /public
address, then either you have incorrectly set up the Route in the /routes/web.php
file (perhaps created a group named "public" or added the /public
URL part to every route), or your domain is pointing to the /your-project
folder incorrectly.
It is possible that you do not have control over which directory the domain name points to, for example, it may be fixed to the "public_html" directory. That's no problem.
Place the contents of the /your-project/public
directory here. Then, at the same level as public_html
, place the your-project
directory. After that, modify all references in /your-project/public/index.php
that point to the directory one level above using ../
. Instead, replace it with ../your-project
.
Example:
# changed directory tree (when has fixed domain's root)
server
├── your-project
│ ├── app
│ ├── routes
│ └── ...
├── public_html <--- domain root
│ ├── index.php
│ └── .htaccess
<?php
// your-project/public/index.php --> public_html/index.php
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
// ../your-project/ instead of ../
if (file_exists($maintenance = __DIR__.'/../your-project/storage/framework/maintenance.php')) {
require $maintenance;
}
// ../your-project/ instead of ../
require __DIR__.'/../your-project/vendor/autoload.php';
// ../your-project/ instead of ../
$app = require_once __DIR__.'/../your-project/bootstrap/app.php';
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
)->send();
$kernel->terminate($request, $response);
Upvotes: 1
Reputation: 4102
For running Apache on Ubuntu, do the following. This assumes you have Composer and PHP already installed.
# create your web directory
sudo mkdir -p /var/www/example.com
# install laravel
cd /var/www/example.com
composer create-project laravel/laravel example-app
# proper ownership
sudo chown -R www-data:www-data /var/www/example.com
# create a configuration
sudo nano /etc/apache2/sites-available/example.com.conf
Then in the file paste
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# SSL configuration, etc.
</VirtualHost>
Then run
# enable your site
sudo a2ensite <your domain>
# disable the default site
sudo a2dissite 000-default
# restart the web server
sudo systemctl reload apache2
Upvotes: 2
Reputation: 163978
Do not modify any Laravel files. Instead configure your web server (Apache or Nginx) to point to the Laravel project's public
directory.
For Apache you can use these directives:
DocumentRoot "/path_to_laravel_project/public"
<Directory "/path_to_laravel_project/public">
For nginx, you should change this line:
root /path_to_laravel_project/public;
Having your document root as /path_to_laravel_project/
alone will create serious security risks, potentially opening your entire app configuration to the internet.
Upvotes: 11
Reputation: 65
Step 1: Put your /public/index.php and /public/htaccess file to your root directory as /index.php and /htaccess .
Step 2: Now Make changes in your index.php
require __DIR__.'/../bootstrap/autoload.php'; //OLD code
$app = require_once __DIR__.'/../bootstrap/app.php';
to
require __DIR__.'./bootstrap/autoload.php'; //NEW code
$app = require_once __DIR__.'./bootstrap/app.php';
Upvotes: 2