This solution does not handle the case of files that actually exists that you may want to access (robots.txt, favicon.ico, other images, etc.). I know for an api backend this might not always be necessary, however we are going to be serving help docs for the api so we will need the frontend.
This solution appears to work because it is abusing the 404 catch and not actually doing a try_files. Try_files would be the ultimate solution however there is still an open bug in nginx using alias and try_files referenced at http://trac.nginx.org/nginx/ticket/97#comment:14 on the nignx site.
I have worked up a solution that solves both problems and from my initial tests will route to files and directories if they exists and if not will fall back to the index.php to allow Laravel to handle the routing. This is what try_files does for you when it works.
I am using this solution on my servers as well as my Homestead box. The only catch obviously is that reprovisioning the server will overwrite the nginx files. Our setup for Homestead is to have the app point to the Angular code base and then add the location /api block to our nginx config.
This should restore Laravel routing to full functionality. This will allow for versioning of the API.
NGINX config and routing example are below.
nginx Config
server {
listen 80; ## Listen on port 80 ##
server_name example.com; ## Domain Name ##
root /home/vagrant/example.com/angular/build; ## Site root for the Angular code ##
index index.html index.php; ## Set the index for site to use ##
charset utf-8; ## Set the charset ##
location / { ## Handle default requests ##
try_files $uri $uri/ /index.html; ## Try files and fall back to index.html ##
}
location /api { ## URL string to use for api ##
alias /home/vagrant/example.com/laravel/public; ## Site root for Laravel code ##
## Check for file existing and if there, stop ##
if (-f $request_filename) {
break;
}
## Check for file existing and if there, stop ##
if (-d $request_filename) {
break;
}
## If we get here then there is no file or directory matching request_filename ##
rewrite (.*) /api/index.php?$query_string;
## Normal php block for processing ##
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
## Don't fail or log request to favicon or robots.txt ##
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
## Access log is off and error log location is set ##
access_log off;
error_log /var/log/nginx/example.com-error.log error;
## Disable sendfile ##
sendfile off;
## Normal php block for processing ##
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
## Don't allow access to .ht files ##
location ~ /\.ht {
deny all;
}
}
Routing example
Route::group(['prefix' => 'v1'], function() {
Route::get('/', ['as' =>'v1', 'uses' => 'LandingController@v1']);
Route::get('users', ['as' => 'users', 'uses' => 'V1\UserController@index']);
});
Route::group(['prefix' => 'v2'], function() {
Route::get('/', ['as' =>'v2', 'uses' => 'LandingController@v2']);
});