InfoWorld how-to's

How-to: Get started with Nginx

Follow these steps to install Nginx on Linux and configure PHP support, virtual hosts, HTTP authentication, SSL support, URL rewrites, and load balancing

server racks airconditioned room 153686889
Thinkstock

InfoWorld how-to's

Show More

Although the most popular Web server in the world is still Apache, Nginx is cutting into that market share in a very significant way. Both versatile and extremely fast, Nginx generally performs faster than Apache right out of the box, especially when serving static content or acting as a reverse proxy server. It's used to serve content for many extremely large-volume websites.

In this how-to, we’ll show you how to get started with Nginx on Fedora, CentOS, and Ubuntu Linux distributions. In addition, we’ll install PHP-FPM to handle dynamic PHP content.

Installing Nginx on Fedora and CentOS

Nginx can run even while Apache is installed on the same system, but we need to make sure Apache is not running at the same time, or at least on the same ports. So let’s make sure Apache isn’t running or set to run at startup. We do that on most Fedora and CentOS installations via the following commands, run as root or with sudo:

$ sudo -i

Alternatively, try this:

$ su –

Now let’s stop Apache and make sure it doesn’t start at boot:

# service httpd stop
# chkconfig httpd off

Those commands should work on all Fedora and CentOS releases, but on later releases using system, you should use the systemd commands:

# systemctl stop httpd.service
# disable httpd.service

Either way, these commands will stop Apache if it’s running and prevent it from starting during a reboot.

Now, let’s install Nginx. To do this, we need to install the EPEL (Extra Packages for Enterprise Linux) and Remi repositories for our release version and architecture.

For CentOS 6 x86_64:

# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

For CentOS 6 i386:

# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

For CentOS 5 x86_64:

# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

For CentOS 5 i386:

# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm

Now, we enable the Remi repository for this installation only, and install the packages we need. If you want to enable the Remi repository globally, edit /etc/yum.repos.d/remi.repo and set enabled=1 for the [remi] repository.

# yum --enablerepo=remi install nginx php-fpm php-common

The above command will install everything we need to run PHP through Nginx including the PHP-FPM CGI handler.

For Fedora 17, 18, 19, 20:

# rpm -Uvh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

Now, substitute your release in the following line for <releasenum>:

# rpm -Uvh http://rpms.famillecollet.com/remi-release-<releasenum>.rpm

Thus, for Fedora 20, you would run the following:

# rpm -Uvh http://rpms.famillecollet.com/remi-release-20.rpm

Now, we can install Nginx with yum:

# yum --enablerepo=remi,remi-test install nginx php-fpm php-common php-mysqlnd

This will install everything we need including Apache updates due to some dependencies. That’s normal and won’t impact Nginx.

After installation, we can start Nginx and make sure it’s running:

# service nginx start

Once the service is started, you should be able to point a Web browser to the IP address of your system and see the default “Welcome to Nginx!” page.

Installing Nginx on Ubuntu

First, let’s stop Apache if it’s running and set it to not start at boot:

$ sudo service apache2 stop
$ sudo update-rc.d apache2 disable

On Ubuntu 12.04 LTS and later, we won’t need to add any repositories to install Nginx, because Nginx is a supported package. We can install Nginx and the PHP packages with apt-get:

$ sudo apt-get install nginx php5-fpm

This will install everything we need to get started. After installation, we can start Nginx and make sure it’s running:

$ sudo service nginx start

Once the service is started, you should be able to point a Web browser to the IP address of your system and see the default “Welcome to Nginx!” page.

Configuring Nginx on all platforms

The configuration for Nginx is the same on all of these distributions, but the file locations may differ. On Fedora and CentOS, you will find the Nginx configuration files under /etc/nginx, with file includes under /etc/nginx/conf.d. This means that if you want to add virtual Web servers, it’s best to add them each in their own separate file under /etc/nginx/conf.d, and their configurations will be included in the global config.

On Ubuntu, the main configuration is also under /etc/nginx/ and /etc/nginx/conf.d, but the Ubuntu concept of sites-available and sites-enabled applies to Nginx exactly as it does to Apache. Thus, you may want to create your virtual server configurations in /etc/nginx/sites-available and symlink them in /etc/nginx/sites-enabled.

If you’re familiar with configuring Apache, you may find Nginx’s configuration file format to be a bit foreign. It does not resemble Apache’s config file at all. In fact, it’s built more like code than a configuration file. The major elements such as server definitions use open and close braces that contain the configuration relevant to those elements. For instance, a server definition might look like this:

server {
    root /usr/share/nginx/www;
    index index.html index.htm;
    location / {
            try_files $uri $uri/ /index.html;
    }
    error_page 404 /404.html;
    location ~ /\.ht {
            deny all;
    }
}

This is a simple configuration that would work as a default, as it will serve any request and does not use virtual Web services. Let’s look at each element.

The server directive contains the configuration elements for this server instance. In this case, it’s the only instance specified. We could specify a server name within this stanza, which would cause Nginx to use this server configuration when that server name was requested. However, in the example, we are using this server example for all requests to Nginx.

The root key specifies the directory that is the document root. All files to be served by this server will be present under that directory. The index key specifies the file name or names that should be served if the request does not specify a file. Thus, if a request came in for http://my.server.name/ and there was a file named index.html in the document root, it would be delivered to the client.

The location directive specifies further configuration that should be bound to a requested location. In this case, it’s the root directory, or /. The try_files key specifies what files to look for in this location based on the request. This default configuration specifies that Nginx should look for files requested by the client, then serve the index if they are not found.

We then see an error_page key that would cause a specified HTML page to be displayed if a "404 – Not Found" error was encountered. Then we see another location directive that uses a filename match to deny access to any files of a type starting with .ht, such as .htaccess files. The ~ character specifies that this location should be a pattern match, not an explicit match like the first location directive above it.

Then we see the braces closing our server stanza. This concludes the configuration for a basic Nginx server.

There are some default configuration elements that concern overall service configuration, not necessarily virtual Web services. In the config file you will find events and http directives that contain configuration elements. These control such things as gzip compression, MIME types, global logging, worker connections, keepalive values, and so forth. For our purposes here they can remain at their default settings.

Working with PHP and PHP-FPM

Unlike Apache, Nginx doesn’t "just work" with PHP or other dynamic languages. It needs to be configured to use a CGI interface that can run the PHP or other dynamic code.

For PHP, this is done with the PHP-FPM package that we installed when we installed Nginx. This is a daemon process that listens on a TCP port or a Unix socket and runs the code as requested by the client, returning the results.

In instances where Nginx and PHP-FPM are running on the same host, we can speed things up by using Unix sockets rather than the TCP connections, which carry more overhead. Thus, we need to modify the PHP-FPM configuration and make sure the service is started.

On Fedora and CentOS, we will find the configuration file we need at /etc/php-fpm.d/www.conf. For Ubuntu, it will be at /etc/php5/fpm/pool.d/www.conf. We need to edit this file.

On Fedora and CentOS:

# nano /etc/php5/fpm/pool.d/www.conf

On Ubuntu:

$ sudo nano /etc/php5/fpm/pool.d/www.conf

Within this file, locate the listen directive. It probably reads listen = 127.0.0.1:9000. This would cause PHP-FPM to listen on the loopback interface, TCP port 9000. Let’s change this to a file name that will be the Unix socket instead. Change the listen line as follows.

On Fedora and CentOS:

listen = /var/run/php-fpm.sock

On Ubuntu:

listen = /var/run/php5-fpm.sock

The only difference here is the file name, which is php-fpm.sock for Fedora and CentOS and php5-fpm.sock for Ubuntu. This is simply to keep in line with the naming conventions in each distribution. You could name this socket anything you wish, as long as you match the socket name in the Nginx configuration.

On Fedora and CentOS only, we also need to modify the permissions of the socket, because the default settings will prevent Nginx from connecting. We need to take the following line:

; listen.group = nobody

Then change it to:

listen.group = nginx

Note that we removed the comment character (;) from the beginning of the line and changed the group name to nginx, which will allow Nginx to read and write to the socket, as the nginx user is in the nginx group. We could have also specified a different listen.mode, such as 0666, which would have allowed any user to read and write to the socket.

Save the file and exit. Use the service command to restart PHP-FPM.

On Fedora and CentOS:

# service php-fpm restart

On Ubuntu:

$ sudo service php5-fpm restart

After restarting PHP-FPM, we should see the socket present in /var/run:

# ls -la /var/run/php-fpm.sock
srw-rw-rw- 1 root root 0 Jun 12 16:49 /var/run/php-fpm.sock

We are now ready to configure Nginx to handle PHP files.

On Fedora and CentOS, edit the /etc/nginx/nginx.conf file:

# nano /etc/nginx/nginx.conf

You can locate the existing PHP-FPM configuration stanza within the server directive and uncomment it, or add a new stanza. It should look like this when you’re done:

location ~ \.php$ {
    root           html;
    fastcgi_pass   unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include       fastcgi_params;
}

This will cause Nginx to match on file names ending in .php and passing those files to the PHP-FPM service for execution. Note that this is not exactly what is in the commented out section of the default configuration. Note the SCRIPT_FILENAME setting is $document_root$fastcgi_script_name, not the default of /scripts$fastcgi_script_name. This is an important distinction.

Now, restart Nginx:

# service nginx restart

Now, create a test PHP script in the document root:

# nano /usr/share/nginx/html/test.php

Paste in this code:

<?php
phpinfo();
?>

Save the file and exit. In a Web browser, open http://<IP address of your system>/test.php. You should see the PHP information page showing you all the details of your new installation.

And on Ubuntu:

Edit the /etc/nginx/sites-available/default file:

$ sudo nano /etc/nginx/sites-available/default

You can uncomment the relevant PHP-FPM configuration or add a new one. It should look like this when you’re done:

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

This will cause Nginx to match on file names ending in .php and pass those files to the PHP-FPM service for execution.

Now, restart Nginx:

$ sudo service nginx restart

Now, create a test PHP script in the document root:

# nano /usr/share/nginx/www/test.php

Paste in this code:

<?php
phpinfo();
?>

Save the file and exit. In a Web browser, open http://<address of your system>/test.php. You should see the PHP information page showing you all the details of your new installation.

If you are having difficulty accessing the server from a browser, your firewall may be interfering. You will need to disable the firewall or allow access to TCP port 80 and potentially port 443 for SSL connections in order for clients to access your new Web server.

On Fedora and CentOS, one of these commands should work to disable the firewall:

# service iptables stop
# systemctl stop firewalld.service

On Ubuntu:

$ sudo ufw disable

Note: This will disable the firewall for the entire server. It’s a better idea to add firewall rules to allow TCP port 80 and 443 through the firewall than to disable the firewall altogether.

Further Nginx configuration

What we’ve built is a basic Nginx installation with PHP support. You can extend the functionality of Nginx from here by configuring elements such as virtual hosts, HTTP authentication, access controls by IP address, SSL support, URL rewrites, and even load balancing. Here are some quick examples.

1 2 Page 1
Page 1 of 2