Jump to content
  • How To Set Up Nginx & PHP 7.1 FPM On Ubuntu 16.04 Server

       (3 reviews)

    Roy

    How To Install Nginx & PHP 7.1 (FPM) On Ubuntu 16.04

     

    Hello, I will be showing you how to install Nginx and PHP 7.1 on an Ubuntu 16.04 server. I made this tutorial while using a stock image of Ubuntu 16.04 LTS server.

     

    Prerequisites

    • Shell access to the Ubuntu 16.04 server.
    • Basic knowledge of Linux.
    • A user with root access (either the root user itself or running commands with sudo).
    • A domain pointing at the Ubuntu 16.04 server (e.g. gflclan.com).

     

    Installing PHP 7.1
    First, you need to install the software-properties-common package via apt:

    sudo apt-get install software-properties-common

    This software provides an abstraction of the used apt repositories. It allows you to easily manage your distribution and independent software vendor software sources.

     

    Next, you need to add the PPA that includes PHP 7.1 packages via apt:

    sudo add-apt-repository ppa:ondrej/php

     

    Now you need to update apt to add the PHP 7.1 packages:

    sudo apt-get update

     

    Next, install the common PHP packages along with PHP FPM via apt:

    sudo apt-get install php7.1-common php7.1 php7.1-cli php7.1-fpm php7.1-json php7.1-opcache php7.1-readline -y

    Keep in mind, this includes the stock packages. You may list additional packages you would like installed by executing sudo apt-cache search php7.1 and running sudo apt-get install <packageName> -y to install them.

     

    Lastly, let’s enable the php7.1-fpm service by executing the following command:

    sudo systemctl enable php7.1-fpm

    This will make it so the PHP 7.1 FPM service automatically starts up on bootup.

     

    There you have it, PHP 7.1 should be installed! You should be able to use the same process with installing updated versions of PHP. For example, instead of using 7.1, you can use 7.2 and so on.

     

    Configuring PHP 7.1 + FPM
    Configuring PHP 7.1 is quite simple, but there are a few ways you can do it. I’m going to show you the way I normally configure PHP 7.1.

     

    Make A New User
    I normally run multiple websites off of one installation. Therefore, I have PHP FPM run under its own user/group for each website (this is typically more secure as well). In this case, we’re going to create a group named site1 and a user named site1.

     

    You can add the group with the following command:

    sudo groupadd site1

     

    You can add the user with the following command (feel free to alter if you have enough knowledge):

    sudo useradd -m -d /var/www/site1 -g site1 -s /bin/false site1


    This will automatically create a directory named site1 in /var/www (Nginx’s default root directory), you will need to put your site files in this folder.

     

    Create A New PHP 7.1 FPM Pool
    PHP FPM pools are configured in /etc/php/7.1/fpm/pool.d/. I normally copy www.conf for each pool/website I make and configure it to my needs. 

     

    Let’s start by changing our current directory to /etc/php/7.1/fpm/pool.d/ to make files easier to copy (we won’t need to enter the full paths). You can do this by executing the following command:

    cd /etc/php/7.1/fpm/pool.d/

    You shouldn’t need root access for this since the directory should be readable and executable by all users.

     

    Next, let’s copy the www.conf file for our site1 website:

    sudo cp www.conf site1.conf

     

    Afterwards, edit the new site1.conf file using the text editor of your choice. I personally prefer Vim:

    sudo vim site1.conf

    If you’re new to Vim, please read the manual to learn how to use it. You can read this tutorial here if you’d like.

     

    You will see something like this:

    ; Start a new pool named 'www'.
    ; the variable $pool can be used in any directive and will be replaced by the
    ; pool name ('www' here)
    [www]
    
    ; Per pool prefix
    ; It only applies on the following directives:
    ; - 'access.log'
    ; - 'slowlog'
    ; - 'listen' (unixsocket)
    ; - 'chroot'
    ; - 'chdir'
    ; - 'php_values'
    ; - 'php_admin_values'
    ; When not set, the global prefix (or /usr) applies instead.
    ; Note: This directive can also be relative to the global prefix.
    ; Default Value: none
    ;prefix = /path/to/pools/$pool
    
    ; Unix user/group of processes
    ; Note: The user is mandatory. If the group is not set, the default user's group
    ;       will be used.
    user = www-data
    group = www-data
    
    ; The address on which to accept FastCGI requests.
    ; Valid syntaxes are:
    ;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
    ;                            a specific port;
    ;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
    ;                            a specific port;
    ;   'port'                 - to listen on a TCP socket to all addresses
    ;                            (IPv6 and IPv4-mapped) on a specific port;
    ;   '/path/to/unix/socket' - to listen on a unix socket.
    ; Note: This value is mandatory.
    listen = /run/php/php7.1-fpm.sock
    
    ; Set listen(2) backlog.
    ; Default Value: 511 (-1 on FreeBSD and OpenBSD)
    ;listen.backlog = 511
    ...

     

    First, we want to change the first uncommented (line without a semicolon at the beginning) from [www] to [site1].
     

    From

    [www]

    To

    [site1]

     

    Second, find the lines starting with user = and group =. We want to change the values after the equal sign to the new user and group we made for the website. Change those lines to this:

    user = site1
    group = site1


    From

    user = www-data
    group = www-data

    To

    user = site1
    group = site1

     

     

    Lastly, we want to find the first uncommented line that starts with listen. By default, it will listen to /run/php/php7.1-fpm.sock. However, I like to change this to something easier to remember. In this case, let’s change it to /run/php/site1.sock.

    listen = /run/php/site1.sock


    From

    listen = /run/php/php7.1-fpm.sock

    To

    listen = /run/php/site1.sock

     

    You are done configuring the PHP 7.1 FPM pool! Everything else should be set up correctly. Feel free to look into configuring PHP FPM further by reading here.

     

    Disable Harmful Functions In PHP
    Securing PHP is very important and there are a few useful guides I will post at the end of the tutorial (or through the comments). The first step I usually take to secure PHP is disabling harmful functions (e.g. functions that will execute commands through the shell).

     

    You will need to open the PHP configuration file using a text editor of your choice. The PHP configuration file will be named php.ini and should be located in /etc/php/7.1/fpm/. I will edit the file using Vim by executing the following command:

    sudo vim /etc/php/7.1/fpm/php.ini

     

    We will need to find the line starting with disable_functions. In Vim, you can hit SHIFT + Colon (:), type /disable_functions, and hit enter. It should then go to the line with disable_functions=. Personally, I like using the following:

    disable_function = apache_child_terminate,apache_setenv,define_syslog_variables,escapeshellarg,escapeshellcmd,eval,fp,fput,ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,highlight_file,ini_alter,ini_get_all,ini_restore,inject_code,mysql_pconnect,openlog,passthru,php_uname,phpAds_remoteInfo,phpAds_XmlRpc,phpAds_xmlrpcDecode,phpAds_xmlrpcEncode,popen,posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_setuid,posix_uname,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,syslog,system,xmlrpc_entity_decode,parse_ini_file,show_source,exec,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,


    From

    disable_functions=...

    To 

    disable_function = apache_child_terminate,apache_setenv,define_syslog_variables,escapeshellarg,escapeshellcmd,eval,fp,fput,ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,highlight_file,ini_alter,ini_get_all,ini_restore,inject_code,mysql_pconnect,openlog,passthru,php_uname,phpAds_remoteInfo,phpAds_XmlRpc,phpAds_xmlrpcDecode,phpAds_xmlrpcEncode,popen,posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_setuid,posix_uname,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,syslog,system,xmlrpc_entity_decode,parse_ini_file,show_source,exec,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,

     

    Lastly, restart the PHP 7.1 FPM service for these changes to take effect:

    sudo systemctl restart php7.1-fpm

    There you have it! Configuring PHP 7.1 + FPM should be complete! There is additional configuration you can do to PHP such as performance tweaking and so on. I will link useful guides at the end of the tutorial and will most likely make some of my own in the future.

     

    Installing Nginx
    Installing Nginx is simple through the APT package manager. You can execute the following command:

    sudo apt-get install nginx -y

     

    I’d recommend downloading and installing the recommended dependencies if asked. After it is installed, let’s enable the service by executing the following command:

    sudo systemctl enable nginx

    This will make it so the Nginx automatically starts up on bootup.

     

    It’s that simple, Nginx is now installed!

     

    Configuring Nginx
    Configuring Nginx is simple since most of the settings are tuned correctly from the installation.

     

    We will make a new configuration file for site1. Site configs are handled in the /etc/nginx/sites-enabled/ directory. However, what I like doing is configuring the site file in the /etc/nginx/sites-available/ directory and creating a symbolic link from /etc/nginx/sites-available/<siteFile> to /etc/nginx/sites-enabled/<siteFile>

     

    First, let’s change our current directory to /etc/nginx/sites-available/:

    cd /etc/nginx/sites-available

    You will not need root access for this since the directory should be readable and executable by all users.

     

    Next, let’s copy the default file for our site1 website. You can do this by executing the following command:

    sudo cp default site1

    Some users may prefer to use site1.conf which is fine since that makes things look cleaner.

     

    We will need to edit the file using a text editor of your choice. I will open it with Vim:

    sudo vim site1

     

    The file will look like this:

    ##
    # You should look at the following URL's in order to grasp a solid understanding
    # of Nginx configuration files in order to fully unleash the power of Nginx.
    # http://wiki.nginx.org/Pitfalls
    # http://wiki.nginx.org/QuickStart
    # http://wiki.nginx.org/Configuration
    #
    # Generally, you will want to move this file somewhere, and start with a clean
    # file but keep this around for reference. Or just disable in sites-enabled.
    #
    # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
    ##
    
    # Default server configuration
    #
    server {
            listen 80 default_server;
            listen [::]:80 default_server;
    
            # SSL configuration
            #
            # listen 443 ssl default_server;
            # listen [::]:443 ssl default_server;
            #
            # Note: You should disable gzip for SSL traffic.
            # See: https://bugs.debian.org/773332
            #
            # Read up on ssl_ciphers to ensure a secure configuration.
            # See: https://bugs.debian.org/765782
            #
            # Self signed certs generated by the ssl-cert package
            # Don't use them in a production server!
            #
            # include snippets/snakeoil.conf;
    
            root /var/www/html;
    
            # Add index.php to the list if you are using PHP
            index index.html index.htm index.nginx-debian.html;
    
            server_name _;
    
            location / {
                    # First attempt to serve request as file, then
                    # as directory, then fall back to displaying a 404.
                    try_files $uri $uri/ =404;
            }
    
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            #location ~ \.php$ {
            #       include snippets/fastcgi-php.conf;
            #
            #       # With php7.0-cgi alone:
            #       fastcgi_pass 127.0.0.1:9000;
            #       # With php7.0-fpm:
            #       fastcgi_pass unix:/run/php/php7.0-fpm.sock;
            #}
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /\.ht {
            #       deny all;
            #}
    }
    
    
    # Virtual Host configuration for example.com
    #
    # You can move that to a different file under sites-available/ and symlink that
    # to sites-enabled/ to enable it.
    #
    #server {
    #       listen 80;
    #       listen [::]:80;
    #
    #       server_name example.com;
    #
    #       root /var/www/example.com;
    #       index index.html;
    #
    #       location / {
    #               try_files $uri $uri/ =404;
    #       }
    #}

     

    The first lines we will look for are the ones starting with listen. You should see two:

    listen 80 default_server;
    listen [::]:80 default_server;

     

    We want to remove the default_server from the first line and comment out the second line by adding a # at the beginning because we aren’t using IPv6. It should look like this:

    listen 80 default_server;
    #listen [::]:80 default_server;


    From

    listen 80 default_server;
    listen [::]:80 default_server;

    To

    listen 80;
     #listen [::]:80 default_server;

     

    The next line you want to look for starts with root. Change this from root /var/www/html to the directory we want to store our website files in. In this case, I want to use the home directory of the new user I created for the website which is /var/www/site1. The line should now look like this:

    root /var/www/site1;


    From

    root /var/www/html;

    To

    root /var/www/site1;

     

    You will then want to find the line starting with index and append index.php after index. I also remove useless index files such as index.nginx-debian.html. The line should look like this:

    index index.php index.html index.htm;


    From

    index index.html index.htm index.nginx-debian.html;

    To

    index index.php index.html index.htm;

     

    The next line should be right under the last line. It should start with server_name. You would put the domains of your website. In this case, my website’s domain is gflclan.com. This is how it should look:

    server_name gflclan.com www.gflclan.com;


    From

    server_name _;

    To

    server_name gflclan.com www.gflclan.com;

     

    Additionally and optionally, you can add access and error logging for the specific website by adding the following two lines:

    access_log /var/log/nginx/site1_access.log;
    error_log /var/log/nginx/site1_error.log;

    You can change the log files if you’d like. You can also comment one out if you do not want to use it. I usually disable the access log on large websites since the file would grow to be very large and keep the error log.

     

    Next, we want to enable handling of the PHP files on the website. If you scroll down, you’ll see a bunch of lines commented out that have to do with PHP:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #       include snippets/fastcgi-php.conf;
    #
    #       # With php7.1-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php7.1-fpm:
    #       fastcgi_pass unix:/run/php/php7.1-fpm.sock;
    #}

    Remove the first comment (#) of each line so it looks like this:
     

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
           include snippets/fastcgi-php.conf;
    
           # With php7.1-cgi alone:
           fastcgi_pass 127.0.0.1:9000;
           # With php7.1-fpm:
           fastcgi_pass unix:/run/php/php7.1-fpm.sock;
    }

     

    Let’s comment out the following line since we’re listening on a socket instead of an address/port:

    #fastcgi_pass 127.0.0.1:9000;


    From

    fastcgi_pass 127.0.0.1:9000;

    To

    #fastcgi_pass 127.0.0.1:9000;

     

    We need to change the socket path on the next fastcgi_pass variable to the socket we made back when configuring PHP 7.1 FPM. The line should now look like this:

    fastcgi_pass unix:/run/php/php/site1.sock;


    From

    fastcgi_pass unix:/run/php/php7.1-fpm.sock;

    To

    fastcgi_pass unix:/run/php/site1.sock;

     

    Now save the file and exit.

     

    We will need to create a symbolic link from /etc/nginx/sites-available/site1 to /etc/nginx/sites-enabled/site1. We can do this by executing the following command:

    ln -s /etc/nginx/sites-available/site1 /etc/nginx/sites-enabled/site1


    Files in the /etc/nginx/sites-enabled/ directory are included in the Nginx config.

     

    Finally, let’s restart Nginx by executing the following command:

    sudo systemctl restart nginx

    You could also use sudo systemctl reload nginx if you don’t want to restart the Nginx server.

     

    That’s it! Nginx and PHP 7.1 FPM should be fully configured to work with each other on the specific website you made! Try accessing the website by going to your domain on port 80 (default).

     

    Useful Guides


    Conclusion
    You should have an Nginx server configured to run with PHP 7.1 and FPM through site1. Additional configuration shouldn’t be required but you can always tweak PHP, FPM, and Nginx settings to make your website perform faster and better. Please ensure any files you put in the /var/www/site1/ directory is owned by the site1 user and group. With that said, most website files will only need permissions of 644 while directories should have 755.

     

    I will be making more guides in the future including how to set up SSL for your website along with FTP users using VSFTPD. This is my first guide regarding Nginx and PHP. If you see anything I can improve on, please let me know! I tried my best to make the guide clean and easy to read.

     

    This guide was written by Christian Deacon (@Roy). If you have any questions, please post a comment!

     

    Thanks for reading!

    Edited by Roy



    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    Nick

       6 of 6 members found this review helpful 6 / 6 members

    This is a very well-written guide to follow step-by-step. Though I do believe you skip too many details (e.g. explaining the difference between sites-available and sites-enabled and why you use a symbolic link would benefit this heavily). You could provide a short explanation and encourage people to look these topics up. You don't really learn much from this guide, but this is a guide on how to set these tools up, so I guess that's alright. However, an introduction would be very nice. This could tell people what problems these tools solve, which tools are available (also tools besides NGINX and PHP-FPM), and why you've picked NGINX and PHP-FPM to solve the problems (pros/cons). 

     

    I also like your "Useful Guides" though a little explanation to each of the links could encourage more people to look at them. 

     

     

    All in all - nice work, @Roy!

    Link to review
    Share on other sites
    Aurora

       4 of 4 members found this review helpful 4 / 4 members

    4.5 / 5

     

    Instructions lack clarity; I have, rather unfortunately, gotten my genitalia stuck in a toaster. Please provide assistence.

    Link to review
    Share on other sites
    Aireesan

       1 of 1 member found this review helpful 1 / 1 member

    Pretty decent guide, though only a few in the community will gain any from it.

    Link to review
    Share on other sites

×
×
  • Create New...