How to configure Virtualmin NGINX for a Laravel application

About Virtualmin NGINX and Laravel

Here are short and long versions on how to get a Laravel Application working with NGINX and Virtualmin. This should also work for YII applications. To get started, publish your app somewhere below /home/sitename (but not public_html). I like calling this directory the short version of my app name because naming it too generic means on a multi-site servers one can get lost.

Then follow the instructions below.

Steps 1 to 3 involves changing all references of public_html to app_name/public
Step 4 is an addition to allow URL rewriting.
Step 5 is simply to restart NGINX.

The short version skips a lot of the default stuff that the Laravel website mentions.


mc -e /etc/nginx/sites-available/

1. Change

root /home/sitename/public_html;


root /home/sitename/app_name/public;

2. Change

fastcgi_param SCRIPT_FILENAME /home/sitename/public_html$fastcgi_script_name;


fastcgi_param SCRIPT_FILENAME /home/sitename/app_name/public$fastcgi_script_name;

3. Change

fastcgi_param DOCUMENT_ROOT /home/sitename/public_html;


fastcgi_param DOCUMENT_ROOT /home/sitename/app_name/public;

4. Add below listen (but could be anywhere). This is the friendly URL rewriter.

location / { try_files $uri $uri/ /index.php?$query_string; }

5. Restart NGINX

service nginx restart

Long Version

Laravel and NGINX works really nicely together, and if you’re using Virtualmin, you’re in even better hands since you’ll be able to configure multiple sites to be served with ease. To get going you have to make at couple of changes the the default configuration file that is generated by Virtualmin. This is easy if you follow the steps below. The key changes that you will make is that the server root, and fastcgi_param SCRIPT_FILENAME and fastcgi_param DOCUMENT_ROOT locations must be updated to specify your application location.

Additionally you can add all the additional directives as specified on the Laravel website here which handles headers, 404s, and a couple of other things. Our complete example below shows you a fully configured configuration file with additional comments embedded to show what we have done.

In this example, let’s say our domain is called and our application is called helloworld. We’ve deployed helloworld in the following directory on the Virtualmin server:


For this example, the following configuration file listed below should work. It’s a blend between the information on the Laravel documentation website, and the pre-existing configuration file created by Virtualmin. See the screenshot at the end of this example if you simply want to change the three important directory locations.

Example configuration file based on and helloworld:

server {

   # Start Laravel Additions
   add_header X-Frame-Options "SAMEORIGIN";
   add_header X-XSS-Protection "1; mode=block";
   add_header X-Content-Type-Options "nosniff";
   charset utf-8;
   location / {
      try_files $uri $uri/ /index.php?$query_string;
   location = /favicon.ico { access_log off; log_not_found off; }
   location = /robots.txt { access_log off; log_not_found off; }
   error_page 404 /index.php;
   location ~ \.php$ {
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
      include fastcgi_params;
      try_files $uri =404;
      fastcgi_pass unix:/var/php-nginx/15574097604771.sock/socket;
   location ~ /\.(?!well-known).* {
      deny all;
   # End Laravel Additions
   # Now:
   # 1. Comment out the Virtualmin location block
   # 2. Copy the NGINX unique socket ID line in the commented block below try_files $uri = 404;
   # 3. There are three references to public_html, change all three to /home/yourdomain/yourapp/public
   # 4. Replace ip_address with the IP address in the existing Virtualmin configuration

   listen ip_address;
   root /home/;
   index index.html index.htm index.php;
   access_log /var/log/virtualmin/mydomain.com_access_log;
   error_log /var/log/virtualmin/mydomain.com_error_log;
   fastcgi_param GATEWAY_INTERFACE CGI/1.1;
   fastcgi_param SERVER_SOFTWARE nginx;
   fastcgi_param QUERY_STRING $query_string;
   fastcgi_param REQUEST_METHOD $request_method;
   fastcgi_param CONTENT_TYPE $content_type;
   fastcgi_param CONTENT_LENGTH $content_length;
   fastcgi_param SCRIPT_FILENAME /home/$fastcgi_script_name;
   fastcgi_param SCRIPT_NAME $fastcgi_script_name;
   fastcgi_param REQUEST_URI $request_uri;
   fastcgi_param DOCUMENT_URI $document_uri;
   fastcgi_param DOCUMENT_ROOT /home/;
   fastcgi_param SERVER_PROTOCOL $server_protocol;
   fastcgi_param REMOTE_ADDR $remote_addr;
   fastcgi_param REMOTE_PORT $remote_port;
   fastcgi_param SERVER_ADDR $server_addr;
   fastcgi_param SERVER_PORT $server_port;
   fastcgi_param SERVER_NAME $server_name;
   fastcgi_param HTTPS $https;
   # This section commented out intentionally because it's been moved up to the Laravel specific section
   #location ~ \.php$ {
   # try_files $uri =404;
   # fastcgi_pass unix:/var/php-nginx/15574097604771.sock/socket;
   listen ip_address:443 ssl;
   ssl_certificate /home/;
   ssl_certificate_key /home/;

If you additionally want all HTTP pages to be served as HTTPS, add another server section below or above this one. The contents of which should be:

server {
   listen ip_address:80;
   rewrite ^/(.*)$1 permanent;



Share this article

Leave a Reply

Your email address will not be published.

Scroll to Top