Install and configure nginx and PHP-FastCGI on Ubuntu 16.04

Updated by Edward Angert

Contribute on GitHub

View Project | View File | Edit File

The nginx web server is a fast, lightweight server designed to efficiently handle the needs of both low- and high-traffic websites. Although commonly used to serve static content, it’s quite capable of handling dynamic pages as well. This guide will help you install and run nginx with PHP via FastCGI on your Ubuntu 16.04 Linode.

Install and configure nginx and PHP-FastCGI on Ubuntu 16.04

The steps in this guide require root privileges. Be sure to run the steps below as root or with the sudo prefix. For more information on privileges, see our Linux Users and Groups guide.

Before You Begin

  • Complete the Getting Started guide, specifically setting the hostname.

  • To confirm your hostname, issue the following commands on your Linode:

    1
    2
      hostname
      hostname -f
    

    The first command shows your short hostname, and the second shows your fully qualified domain name (FQDN).

  • If you are new to Linux systems administration, you may want to consider the Introduction to Linux Concepts guide and the Linux Administration Basics guide.

  • Update your system:

    1
    sudo apt-get update && sudo apt-get upgrade
    

This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, see the Linux Users and Groups guide.

Install nginx, PHP for Processing, and Required Packages

Install the nginx web server and PHP dependencies:

1
sudo apt-get install nginx php7.0-cli php7.0-cgi php7.0-fpm

Configure nginx Virtual Hosting and the PHP Processor

In this guide, the domain example.com is used as an example site. Substitute your own FQDN or IP in the configuration steps that follow.

Nginx uses server directives to specify name-based virtual hosts. Nginx calls these server blocks. All server blocks are contained within server directives in site files, located in /etc/nginx/sites-available. When activated, these are included in the main nginx configuration by default.

  1. Nginx includes a sample configuration that you may use as a template. To create a new file with a basic server block for configuration, enter the following command, replacing example.com with your domain:

    1
    tail /etc/nginx/sites-available/default -n 13 | cut -c 2- | sudo tee /etc/nginx/sites-available/example.com 1> /dev/null
    

    The command above reads the example server block contained in the last 13 lines of the default site file, cuts out the # comment symbols, and outputs the result to a new site file. For added security, there is no visual output.

    Alternatively, you may manually copy the last section from /etc/nginx/sites-available/default into a new file, /etc/nginx/sites-available/example.com. You will have to manually remove the # in front of the relevant lines.

  2. You should now have the following server block in the nginx virtual host configuration. Replace all instances of example.com with your domain, modify the root path as shown below, and add the location ~ \.php$ block:

    /etc/nginx/sites-available/example.com
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    server {
        listen 80;
        listen [::]:80;
    
        server_name example.com;
    
        root   /var/www/html/example.com/public_html;
        index  index.html index.php;
    
        location / {
            try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                include fastcgi_params;
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                fastcgi_param SCRIPT_FILENAME /var/www/html/example.com/public_html$fastcgi_script_name;
        }
    }
    
  3. Create the root directory referenced in this configuration, replacing example.com with your domain name:

    1
    sudo mkdir -p /var/www/html/example.com/public_html
    
  4. Enable the site, disable the default host, and restart the web server:

    1
    2
    3
    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled
    sudo rm /etc/nginx/sites-enabled/default
    sudo systemctl restart php7.0-fpm nginx
    

    To deactivate a site, simply delete the symbolic link:

    1
    2
    sudo rm /etc/nginx/sites-enabled/example.com
    sudo systemctl restart nginx
    

    The source file is saved, and the site can be re-enabled at any time by recreating the symbolic link.

If you are using nginx to host more than one site, create multiple virtual host files using the method above.

You may also want to edit the http block in /etc/nginx/nginx.conf, which applies across all sites and allows the following options, among others:

  • Hide HTTP header information using server_tokens
  • Configure SSL/TLS settings
  • Customize log file paths

Important Security Considerations

If you’re planning to run applications that support file uploads (images, for example), the above configurations may expose you to a security risk by allowing arbitrary code execution. The short explanation for this behavior is that a properly crafted URI which ends in “.php”, in combination with a malicious image file that actually contains valid PHP, can result in the image being processed as PHP.

To mitigate this issue, you may wish to modify your configuration to include a try_files directive as shown in this excerpt:

/etc/nginx/sites-available/example.com
1
2
3
4
5
6
7
location ~ \.php$ {
    try_files $uri =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/html/example.com/public_html/$fastcgi_script_name;
}

Additionally, it’s a good idea to secure any upload directories your applications may use. The following configuration excerpt demonstrates securing an /images directory:

/etc/nginx/sites-available/example.com
1
2
3
4
5
6
7
8
location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
    if ($uri !~ "^/images/") {
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/html/example.com/public_html/$fastcgi_script_name;
}

Test PHP with FastCGI

Create a file called test.php in your site’s public_html directory with the following contents:

/var/www/html/example.com/public_html/test.php
1
<?php phpinfo(); ?>

When you visit http://www.example.com/test.php in your browser, the standard “PHP info” output is shown.

Congratulations, you’ve configured the nginx web server to use PHP-FastCGI for dynamic content!

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

This guide is published under a CC BY-ND 4.0 license.