Chapter 26

Nginx Web Server Management

This chapter covers configuration and management of the Nginx web server and includes an overview of some of the major components of the server and discussions of server configuration. In this chapter, you learn how to start, stop, and restart Nginx using the command line. The chapter begins with some introductory information and then shows you how to install, configure, and use Nginx.

About the Nginx Web Server

Pronounced “engine-x,” Nginx is a lightweight and extremely fast web server. It is free and open source. Some well-known websites, such as GitHub, Netflix, and WordPress.com, use Nginx because it is stable and fast under high-traffic conditions while using few resources. It is not as configurable as Apache, but for specific use cases, it is an excellent option and is quite easy to set up and use.

News

The W3Techs website, which tracks trends on the Web, posted an article in July 2013 titled “Nginx just became the most used web server among the top 1000 websites (see http://w3techs.com/blog/entry/nginx_just_became_the_most_used_web_server_among_the_top_1000_websites).” The article summary says that “34.9% of the top 1000 web sites rely on Nginx. That makes it the most trusted web server on high traffic sites, just ahead of Apache.”

The original design of Nginx was created to allow higher numbers of concurrent website requests. Larger websites often have tens of thousands of clients connected simultaneously, each one making HTTP requests that must be responded to. The designers of Nginx heard this problem described as C10K and decided they could write a web server that would be capable of serving at least 10,000 clients simultaneously.

The c10k problem

The canonical website for learning more about this problem is www.kegel.com/c10k.html. The article provided at this link is from the early 2000s and describes ideas for configuring operating systems and writing code to solve the problem of serving at least 10,000 simultaneous clients from a web server. Today, this problem is even more common, and with the continuing maturity of Nginx, lighttpd, and other web servers, many of the largest, highest-traffic sites have switched away from Apache.

Newer versions of the Apache web server and other modern web servers rely on the concept of threads. Threads are kind of like lightweight processes. This deserves some explanation. A process is a specific instance of a computer program running. The process contains both the machine code (the binary, or the compiled version of the program that the computer processor can understand and obey—which is either precompiled as in C or C++ programs or may be the output of a just-in-time compilation as happens with languages like Python or Perl) as well as the current activity of that program, such as the calculations it is performing or the data it stores in memory on which it is operating. Serving an HTTP page by running a complete process each time would be bad because the server’s resources would be quickly used up if the site were even moderately popular. Process after process would be started, and they would fight for attention. A thread is the ordered control of a program: First, do this; then, do that; finally, do this other thing. One process may control many threads. This is good for resource management. By using threads instead of processes, a larger number of client requests can be served using fewer system resources than with a process-based server.

Most web servers have traditionally been either process based or thread based. There are also examples of hybrid models, where many multithread processes are used. Process-based servers are great because they are stable, and the crash of one process does not affect other processes. However, they cannot handle as many clients because the creation and destruction of all of those processes creates a lot of processor overhead and requires a large amount of memory. Thread-based servers are great because requests can share memory, making them more efficient and thereby able to serve more requests more quickly. However, a crash in one thread could bring down the entire server.

What makes Nginx different is that it uses an event-driven architecture to handle requests. Instead of starting a new process or a new thread for each request, in an event-driven architecture, the flow of the program is controlled by events, some form of message sent from another process or thread. Here, you have a process that runs as a “listener” or an “event detector” that waits for a request to come in to the server. When the request arrives, instead of a new process starting, the listener sends a message to a different part of the server, called an event handler, which then performs a task. The simplified outcome of serving web pages this way is that less processor time and less memory are needed. There are some significant difficulties inherent in using this method, not the least of which can be greater code complexity, which can make fixing bugs, adding features, and understanding code as a newcomer (or even a returning veteran of the same codebase who has been away from it for a little while) more difficult.

Nginx is designed to scale well from one small, low-powered server up to large networks involving many servers.

For configuration, Nginx uses a system of virtual hosts, similar to Apache, and a similar set of configuration files. The differences are semantic and not terribly difficult. You can create URL rewrites in Nginx using a rather different syntax. In addition, there is nothing similar to Apache’s rewrite conditions. Occasional blog posts and web tutorials give some workarounds to handle some of the common forms, but if this is something you do often, you might not want to use Nginx.

One file that many people use and love in Apache is .htaccess. There is nothing similar to that in Nginx, so if you need the ability to make changes to rewrites or configurations without restarting the server, you are out of luck. This is probably the primary reason that you don’t see shared hosting offering Nginx.

Finally, another well-documented option is to use both Apache and Nginx together, with Apache handling any and all dynamic requests and Nginx handling all static requests. This is faster and lighter than using Apache alone but comes with the burden of added complexity and the increased potential for problems that complexity brings.

Installing the Nginx Server

You can install Nginx through APT or build it yourself from source code. The Nginx source builds on just about any UNIX-like operating system and on Win32.

If you are about to install a new version of Nginx, shut down the old server. Even if it’s unlikely that the old server will interfere with the installation procedure, shutting it down ensures that there will be no problems. If you do not know how to stop Nginx, see the section “Configuring the Nginx Server,” later in this chapter.

Installing from the Ubuntu Repositories

You can install the nginx package from the Ubuntu software repositories. Updated packages usually contain important bug and security fixes. When an updated version is released, install it as quickly as possible to keep your system secure.

For more information about installing software from the Ubuntu repositories, see Chapter 9, “Managing Software.”

Building the Source Yourself

You can download the Nginx source directly from https://wiki.nginx.org/Install.

When you have the tar file, you must open it in a temporary directory, such as /tmp. Opening this tar file creates a directory called nginx_version_number, where version_number is the version you have downloaded (for example, nginx_1.11.3).

Tip

As with many other software packages distributed in source code form for Linux and other UNIX-like operating systems, extracting the source code results in a directory that contains a README and an INSTALL file. Be sure to peruse the INSTALL file before attempting to build and install the software.

Using ./configure to Build Nginx

To build Nginx, run the ./configure script in the directory just created by using this command:

matthew@seymour:~$ ./configure

This generates the makefile that is used to compile the server code.

Next, run make to compile the server code:

matthew@seymour:~$ make

When the compilation is complete, install the server. This may only be done using admin privileges:

matthew@seymour:~$ sudo make install

Tip

Using Ubuntu’s version of Nginx until you really know what happens at system startup is strongly recommended. No “uninstall” option is available when you install Nginx from source! For the remainder of this chapter, we assume that you have installed Nginx this way. If you install from source, you should check the Nginx documentation as there may be differences from what we describe here.

Configuring the Nginx Server

You can now configure the server. Nginx is most commonly run using virtual hosts, like what most people do with Apache these days. The process is similar, with mainly syntax differences.

If you install using the package manager, all configuration files for Nginx are located in /etc/nginx. The primary configuration file is /etc/nginx/nginx.conf. Here is an example of that file:

user www-data;
worker_processes  1;

# error_log  /var/log/nginx/error.log;

events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;

    sendfile        on;

    tcp_nopush     on;
    #tcp_nodelay     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    include /etc/nginx/sites-enabled/*;
}

The nginx.conf file contains these parts:

user—Sets the system user that will be used to run Nginx. This is www-data by default. You can add a group to this setting by inserting a second entry:

user www-data;

worker processes—Allows you to set how many processes Nginx may spawn on your server. The default value of 1 is fine for most users, although some recommend setting this as high as 4. You can experiment, but do so carefully.

error_log—This is commented out in this example. You can set the location for an error log by removing the # that marks the line as a comment that should not be processed by Nginx and adjusting the listed directory location, if you don’t want to use the default log location.

events and worker_connections—These settings adjust how many concurrent connections Nginx will allow per process. It may be helpful to think of it this way: worker_connections times worker_processes will give you the maximum number of clients that may connect to your server concurrently. Memory plays a factor in whether your server can actually serve all the permitted connections you configure, so if you aren’t sure whether your server has enough memory to go higher, leave both settings at their defaults, and you should be fine.

http—This section contains the base settings for HTTP access:

Leave the include and default_type lines alone unless you enjoy trying to figure out why content is not being displayed or you know you must adjust which types of content are permitted.

Feel free to adjust the location of the access_log, which records all attempts to connect to your server, or comment out the line to disable it.

sendfile is used when you permit Nginx to ignore the contents of the file it is sending, such as when serving larger files that do not require a multiple-request-and-confirmation system when being served, thereby freeing system resources for items that do require Nginx to watch over. Leaving this setting on unless you know why you are turning it off is recommended because it saves resources when serving things like graphics.

tcp_nopush sends HTTP response headers in one packet, and this is actually a pretty good thing, but experimenting with it is okay.

tcp_nodelay is for use with items that do not require a response, but most general web use does demand responses, so this is often best commented out, although trying it to see whether it makes a difference in your circumstance is okay.

keepalive_timeout sets the number of seconds that Nginx will keep a connection open when a request is made. The default is to keep this connection open for more than a minute, which seems a bit odd because you have a limited number of connections available, and keeping a connection alive prevents another requester from using that slot again until the timeout occurs. Setting this to a low number like 2 or 3 seconds seems to permit more people to connect in a minute than would be able to do so otherwise. If you are serving a website with little traffic, the setting doesn’t matter. If you have a lot of traffic, using a lower number is generally a good idea.

gzip allows the use of on-the-fly gzip compression, which can make data transfers a bit faster.

include defines files that are located outside the nginx.conf file that are to be read by Nginx and used for its configuration. You can include multiple files; just create a new line for each. Our example includes a directive to include everything listed in a directory that is generally used for virtual hosts, as described in the section “Virtual Hosting,” which follows. You could place a server variable here and define it (as you will do in the “Virtual Hosts” section), instead of the include, but if you have multiple sites, configuring how Nginx works for each site individually can be useful, especially if you have one site that has a lot of traffic and another that has little.

Whenever you make a change to the nginx.conf file, you must restart Nginx to reload the configuration into Nginx for the changes to take effect, like this:

matthew@seymour:~$ sudo systemctl start nginx

Some prefer to stop and start it, perhaps doing the configuration work in between. This is quite common as in the past Nginx had a habit of not performing restarts perfectly. In our experience, bad resets are rare, but using this method prevents any doubt:

matthew@seymour:~$ sudo systemctl stop nginx
matthew@seymour:~$ sudo systemctl start nginx

Virtual Hosting

One of the most popular services to provide with a web server is to host a virtual domain. Also known as a virtual host, a virtual domain is a complete website with its own domain name, as if it were a standalone machine, but it’s hosted on the same machine as other websites.

Nginx implements this capability in a simple way: Just create a configuration file for your virtual host, name it for that host, and place it in /etc/nginx/sites-enabled. We prefer to place our files in /etc/nginx/sites-available and then create a symlink in sites-enabled, but that is not a requirement. Doing so does allow you to disable one out of several sites by simply deleting the symlink and reloading the configuration or restarting Nginx while preserving the complete configuration for the site, so we recommend you give it a try.

You can place the files for your website wherever you like. The configuration files for Nginx tell the web server where to find them. We like to create them in the main website creator’s/maintainer’s directory, but others prefer /var/www, and still others opt for a different location. Choose a location you like and make a note of it. You will need it shortly.

Here is an example of a file for a virtual host, which we will call yourdomain.com. Name the file yourdomain.com and place it in sites-enabled or sites-available, as described earlier. This file includes comments that will help you fill in your specific details:

#this first server module is just a rewrite directive – it is not required, and you
#can make the rewrite go the other way, to force NOT using www
server {
  listen   80;                       #sets the HTTP port from which the website is served
  server_name  www.yourdomain.com;  #names the server using the www prefix

  #if a server request is made without www, this next line will rewrite it
  rewrite ^/(.*) http://yourdomain.com/$1 permanent;
  }

#this second server module tells Nginx where to find the files when requested
server {
  listen   80;                      #sets the HTTP port from which the website is served
  server_name  yourdomain.com;     #names the server being configured
  location / {                      #sets the location of the files being served
    root  /home/<yourusername>/public_html/yourdomain.com/; #top directory for the site
    index index.html;
    }
  }

Earlier in this section, we mentioned that you may place the files for your website wherever you like. The root line in the file just created is where you place this information. Here we use <yourusername>’s personal home folder and place within it a directory called public_html specifically created for holding website files. Because our example anticipates serving multiple websites with this one server, it goes further and creates a directory for the sample website, yourdomain.com.

At this point, everything should work for simple HTML sites. To add additional domains, repeat these steps for each domain being served.

Setting Up PHP

If you have CGI or other script content, such as a website written in PHP, like WordPress or Drupal, you have more work to do. While the ability to serve PHP is available by default in Nginx (it didn’t use to be), it still requires additional setup. In this section you will add the ability to serve PHP content to an existing Nginx server. As a result, there are some PHP-specific parts to this process; they should be obvious.

First, you need to make sure PHP is installed on the server. There are many ways to do this. For this example, you can use PHP-FPM, which you can learn more about at https://php-fpm.org.

Install the following packages: php7.4-cli, php7.4-cgi, psmisc, spawn-fcgi, and php7.4-fpm.

Edit the file /etc/php7/fpm/pool.d/www.conf to make php-fpm use a UNIX socket instead of a TCP/IP connection by finding this line:

listen = 127.0.0.1:9000

and replacing it with this:

listen = /tmp/php7-fpm.sock

This is where you need to check the requirements of whatever PHP-based application you intend to install and use. Some require other PHP extensions. You may also need a database. We will skip this step as the details differ for each application, but this is when you would likely want to take care of these details, although you can probably make them up later. If all you want to do is serve PHP scripts that you have written or run them on your server, you are probably fine not worrying about this and moving on.

Next, you need to edit either /etc/nginx/nginx.conf or the file for your virtual host, like /etc/nginx/sites-enabled/yourdomain.com from the earlier example, to include information that Nginx needs to be able to deal with PHP content. Editing either will work; the difference is that editing the virtual host file will affect only that website, whereas editing nginx.conf will affect everything on your server.

Here is an example of an edited server module in one of these files. Note what is moved and what is added from the previous example:

server {
  listen   80;                      #sets the HTTP port from which the website is served
  server_name  www.yourdomain.com;  #names the server using the www prefix
  #if a server request is made without www, this next line will rewrite it
  rewrite ^/(.*) http://yourdomain.com/$1permanent;
  }

#this second server module tells Nginx where to find the files when requested
server {
  listen   80;                      #sets the HTTP port from which the website is served
  server_name  yourdomain.com;      #names the server being configured
  root  /home/<yourusername>/public_html/yourdomain.com/; #top directory for the site
  index index.html index.php;
  client_max_body_size 1G;
  fastcgi_buffers 64 4K;
  location / {                      #sets the location of the files being served
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_split_path_info ^(.+.php)(/.+)$;
    fastcgi_pass unix:/tmp/php5-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
  }

Restart Nginx, and you are all set. See https://wiki.nginx.org/PHPFcgiExample for more details.

Adding and Configuring Modules

The topic of adding and configuring modules is bigger than can or should be covered in this book, where we only intend to introduce you to a wide range of technologies and features available in, with, and for Ubuntu and help you acquire a basic competence with them. In this chapter, we have only set up a basic server. It will serve the needs of most people, but tons of other settings are available for you to use, and many other configuration options exist for core modules and even optional modules you can add to your server.

Adding additional modules is something that must be done when Nginx is compiled, so if you need something that is not included by default in the package from the Ubuntu repositories, you need to read the official documentation, download Nginx from the website, and compile it yourself. The best way to start is to immerse yourself in the official module documentation at https://nginx.org/en/docs/.

To configure an enabled module, whether a default module or an optional one, start at the same documentation, find the module you want to configure in the list, and click its entry to learn about the various options. Even the Core module configured in the nginx.conf example has a ton of extra options. You may not need any of them, but you may find something useful.

HTTPS

Nginx comes with the ability to encrypt communications using openssl. What this means is that your website can be accessed using https:// instead of just http://, and all communications to and from the site will be encrypted.

For HTTPS to work, a certificate and a key are required. You should either generate a self-signed certificate and key (which is adequate for internal use or for personal sites) or buy a certificate from a certificate authority (CA) (which is necessary if you want anyone to trust your site for commercial ventures).

To generate a key for the certificate, use this command:

matthew@seymour:~$ openssl genrsa -des3 -out server.key 2048

This generates a basic key using Triple DES and 2,048-bit encryption. See the man page for openssl for more information about possible settings.

To generate a certificate signing request (CSR), use this command:

matthew@seymour:~$ openssl req -new -key server.key -out server.csr

You are then asked for some information to complete the request.

To generate a self-signed certificate, use this command:

matthew@seymour:~$ openssl x509 -req -days 365 -in server.csr -signkey server.
key -out server.crt

This creates a certificate that is valid for 365 days. Certificates, even from vendors, have expiration dates. Certificates should be renewed regularly to reassure your site visitors that they are dealing with who they think they are dealing with.

To copy the certificate to its proper location, use this command:

matthew@seymour:~$ cp server.crt /etc/nginx/ssl/

To copy the key to its proper location, use this command:

matthew@seymour:~$ cp server.key /etc/nginx/ssl/

Next, you must modify your Nginx configuration to use the server certificate and key files. This is done in the server module of the config file. Here is the earlier example, with the additions you need now in bold:

server {
  listen   80;                  #sets the HTTP port from which the website is served

  listen  443 ssl;
  server_name  www.yourdomain.com;  #names the server using the www prefix

  ssl_certificate /etc/nginx/ssl/server.crt
  ssl_certificate /etc/nginx/ssl/server.key

  #if a server request is made without www, this next line will rewrite it
  rewrite ^/(.*) http://yourdomain.com/$1 permanent;
  }

You can now access web pages on your server by using https://. This is adequate for testing and internal use but not for anything else.

The best thing to do if you are going to host a professional site is to use a CA. Every CA has a preferred method, and you should read a CA’s requirements before you use that CA. The basic process is usually like this:

  1. Create a private and public encryption key pair.

  2. Create a certificate based on the public key.

  3. Create a certificate request with information about your server and the company hosting it.

  4. Send your certificate request and public key along with proof of your company's identity and payment to the CA.

  5. Wait for the CA to verify the request and your identity and send back a certificate like the self-signed one created earlier, but signed by the CA.

  6. Install that certificate on your server and configure Apache2 to use it.

A CA-signed certificate provides advantages. First, browsers are built with data about most CAs and automatically recognize a signature from one of them on your certificate most of the time. A self-signed certificate will cause the browser to display a rather scary-looking (to a nontechnical person) warning and require the user to acknowledge it before viewing your site. In addition, when the CA issues the signed certificate, it is guaranteeing the identity of the organization providing the web pages.

To learn more about certificates and keys, including installation of keys and certificates you pay for, see https://tldp.org/HOWTO/SSL-Certificates-HOWTO/index.html.

Reference

https://nginx.org/en/docs/The Nginx wiki website, where you can find extensive documentation and information about Nginx, including installation instructions, downloads, and tips for configuration and use

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.131.47