How to Compile, Install and Configure Latest Nginx on CentOS

The Nginx documentation provides thorough and detailed information for reference on how to install Nginx in different ways on different operation systems. If you do not have time to read that, and need to install Nginx in a limited time, this article is a guide for you to install and configure Nginx in best practices.

This article will use the currently latest stable version 1.20.2 of Nginx as an example to show how to compile, install, and configure Nginx on CentOS. The full process has been tested as working on CentOS 7, CentOS 8, and CentOS Stream 8.

A root user role is required to follow the commands in this article. If you are not the root user, please make sure to add “sudo” before each command, or switch to the root user by command below:

sudo -s

We will use yum command for any package related operation. Please note that on CenOS 8, CentOS Stream 8 and later versions of CentOS, yum command is a symbolic link to dnf binary and was replaced by dnf command.

1 Choose installation method

Nginx can be installed either by package manager or from source code compilation. Both ways have pros and cons. Using package manager is fast but lacks the support for customized configuration. Install from source supports various customization, but you need to manage all the dependencies by yourself.

There are two other problems with installing by package manager: if installed from system library, it is usually not the latest version; if installed from the library provided by Nginx, we can get the latest version, but installation files will be messed up with system built-in software files which would carry a conflict risk.

2 Download Source

Nginx has two versions: Mainline version and Stable version. Mainline version is the latest version. Although it is not likely to have usability problem, it may include some experimental modules and have some new bugs. Stable version does not include all of the latest features, but it has critical bug fixes that are always backported to the mainline version. Nginx recommends the stable version for production servers. We will also use this version for examples in this article.

We will get the download link of latest stable source package from:

First let us change the directory to system local source folder, then we will download the package using the link we got:

cd /usr/local/src
curl -LO https://nginx.org/download/nginx-1.20.2.tar.gz

3 Compile Nginx

Compared to installing Nginx by package manager, compiling Nginx from source takes more steps, and is more likely to get us into unexpected troubles. However, as long as we are patient enough to figure out the cause of the problem, it should be easily solved.

Compiling Nginx is a two-stage process. First we will use the customization support of Nginx configure script to generate a Makefile (a set of task rules to be executed). Then these rules will be used by Make tool to build Nginx automatically. We will talk in more details in the following.

3.1 Prepare Environment

Nginx is written in C language. Before compiling Nginx, we need to make sure C Compiler is installed on CentOS. We will use GCC (GNU Compiler Collection) as the C compiler. You can use any C compiler you like.

We also need to install the build automation tool Make. It will automatically build executable programs and libraries from source, according to the Makefile generated from configure script.

You may use following command to install GCC and Make on CentOS:

yum install -y gcc make

3.2 Configure Features

First we will unpack the Nginx source package and switch to the directory of the source (note that we will stay in this directory for all operations unless otherwise specified):

tar -xvf nginx-1.20.2.tar.gz
cd nginx-1.20.2

You will find a Shell script named configure under this directory, which is a configure script file from Nginx source. This script file does two things: one is to customize Nginx features in a fine-grained manner by the rich options it provides; the other is to match the libraries in system and the libraries Nginx depends on to be compiled (if one library is missing, it will stop and give you the library name to fix).

You may run commands below to check all available configure options from the help manual (press q to quit):

./configure --help | less

You can also refer to Building nginx from Sources page of Nginx documentation, where each option is given with a brief description including reference link of the feature mentioned.

As refer to which options to use, it depends on features you need. For example, if you want Nginx to support HTTPS protocol, then SSL module is required to install, otherwise it is not required.

The Nginx in this article is compiled for use as web server, and need to support SSL, HTTP/2, as well as getting IP address from specified HTTP request header. These features correspond to configure options as follows:

Configure OptionsFeatures
–prefixTo specify installation directory
–with-http_ssl_moduleTo support HTTPS protocol
–with-http_v2_moduleTo support HTTP/2
–with-http_realip_moduleTo get IP address from specified request header

To support features mentioned above, there are software libraries that Nginx depends on while compiling. If a library is missing, the running of configure script will be interrupted to throw prompt. Each interruption gives one prompt only, so to avoid being interrupted many times, and if you need all features mentioned, you can run below command to install these libraries for operation system:

yum install pcre-devel zlib-devel \
openssl-devel 

After installing the library dependencies for compilation, we may run the configure script to configure:

./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module

Please note that the directory specified by --prefix option in above command is the location Nginx to be installed. You can specify any location you like, but as for best practice, the location of system local programs is a good choice. You can actually ignore this option, but Nginx installation files will be distributed everywhere, spreading into etclib, and bin folder under /usr/local.

After executing the configure script, if message looks like below, it means everything is fine and we are ready to compile:

...
Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

3.3 Perform Compilation

Now you may run following command to compile Nginx source code:

make

If your server configuration is high, you may use the option -j of make command to start multiple processes to speed up compiling. For example, to compile with 3 processes, use command make -j3.

The compiling time depends on server configuration, the available system resources, and the specific configuration for compiling. Compiling Nginx does not eat up many system resources. Normally, even a server with low configuration can compile successfully and quickly.

After the successful compilation, you may see message below:

...
-ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz \
-Wl,-E
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
	-e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
	-e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
	-e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
	< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory '/usr/local/src/nginx-1.20.2'

4 Install Nginx

After the compilation, we can use following command to install Nginx under the directory we specified eariler:

make install

So far we have finished the Nginx installation. If this is your first time to install Nginx, to make it easier to execute Nginx commands later, please add the path of Nginx executable file to system environment variable PATH by commands below:

echo 'export PATH="/usr/local/nginx/sbin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Now you may check the Nginx version:

nginx -v

5 Configure Nginx

The Admin Guide page of Nginx documentation provides rich configuration guides for different usage of Nginx, such as Load Balancer, Web Server, Mail Proxy, etc. This tutorial only configure a simple web server to access static files (such as HTML pages, images, etc) in best practices.

5.1 Assign User Rights

There are two kinds of processes after Nginx get started, which are master process and worker process. There is only one master process, and its role is to read and evaluate configuration, and manage the pool of processes. There can be more than one worker processes (configured by worker_processes directive of configuration file), and its role is to handle requests.

The master process must run as administrator account (root). This is because in Linux system, the administrator account (root) privilege is required to bind the local TCP port lower than 1024. Since the default ports used by web server for HTTP protocol and HTTPS protocol are 80 and 443, to bind them Nginx must have administrator privilege. Besides, Nginx also need the root privilege to read configuration files.

The worker process needs to run as normal user account. This is because it is the worker process that actually handle requests, and by restricting its permissions, the potential hazard to the safety of operation system is avoid. Normally this account is a dedicated account of web server, like www-data (will be configured in following Nginx configuration), and usually it is the same account as for FastCGI (like PHP-FPM) program.

5.2 Create Dedicated Account

As we mentioned earlier, web server typically use dedicated account to store, read and write web files (including image, HTML files and web applications).

If this account has not been created for web server, you may run command below to create a system account named “www-data” that does not have login permission:

useradd www-data -s /sbin/nologin

5.3 Modify Configuration File

Nginx provides an out-of-the-box configuration file with an example of static web server configuration that can be accessed as long as Nginx is started. In addition, the configuration file provides some other configuration examples that can demonstrate Nginx capabilities except that they are annotated by default.

In order to explain directives in configuration file with no other information, we will not use the default configuration file. We would create a new configuration file and put in directives we need.

First of all, we will backup Nginx default configuration file by command below:

mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak

Then create a new configuration file for Nginx, named as nginx.conf which is the same name as the default file, with your favorite editor (here we use vi editor):

vi /usr/local/nginx/conf/nginx.conf

Copy the content below and paste it to the new created configuration file, then save and quit the editor (for vi editor: press ESC + input :wq + press Enter):

user  www-data;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /home/www-data/www;
            index  index.html index.htm;
        }
    }
}

There are 13 directives in above configuration, including 9 simple directives and 4 block directives (followed by curly braces{}). If a block directive can have other directives inside braces, it is called a context.

Some of these directives are for Nginx Core functionality, used to configure functionalities related to the operation of Nginx program itself, like user, worker_processes, events, worker_connections and include; Some are for Module ngx_http_core_module of Nginx, for example, they are used to configure functionalities related to HTTP server, like http, default_type, server, listen, server_name, location and root; While some are for Module ngx_http_index_module of Nginx, used to handle requests that ended with slash character (/), like index.

The 1st directive is user, which is used to set user and user group that operate Nginx worker process. Here it is set to the dedicated account created earlier, so that Nginx have the permission to access files whose owner is this user.

The 2nd directive is worker_processes, which is used to define the number of worker processes. If your server configuration is high, you may modify the value to increase the number of worker processes and improve the performance of web server. Although the optimal value for this directive depends on many factors, it can be set to the number of CPU cores, or set to “auto” (automatically detects the number of CPU cores).

The 3rd is a block directive called events. It is a context in which the directives that affect connection processing are specified.

The 4th directive is worker_connections that inside the block directive “events”. It is used to set the maximum number of simultaneous connections that can be opened by a worker process. It can be set to the maximum number of files opened per worker process by operation system (value from command ulimit -n), like 1024 in example.

The 5th is a block directive called http, which is used to control HTTP communication by directives inside. The following 8 directives are inside it.

The 6th directive is include, which is used to include another file. In our example, a Nginx prebuilt file of mime.types is included. This file only has a block directive “types”, which is used to map file extensions to MIME types. When client requests files with certain extension, Nginx will response with corresponding MIME type.

The 7th directive is default_type, which defines the default MIME type. When Nginx can not find MIME type for certain extension, it will use this default type. In our example, this is set to “application/octet-stream”, which means by default a binary file will be responded to client, asking to download the file.

The 8th is a block directive called server. By directives it holds, it sets configuration for a virtual server. The following directives are inside it.

The 9th directive is listen, which usually sets the request port for virtual server. If no specific, we need to set this value to 80, the default port number of HTTP protocol. If HTTPS protocol is asked by virtual server, the default port number 443 will be used.

The 10th directive is server_name, which sets names of a virtual server. It is usually used to bind one or more domain names. Since domain binding is beyond the scope of this article, we just set it to localhost in our example.

The 11th is a block directive called location, which defines the prefix strings to be compared against Request URI [1]. If the request URI matches the prefix, then appends the request URI to the path set by root directive to form the requested file path on local file system. In our example, we set the prefix strings as slash character(/), which means to match all requests, and if the requested file path exists, Nginx will send this file.

The 12th directive is root, which sets the root directory for requests. It can be used in many context like http, server, location etc. The default value of this directive is html folder in installation directory. In our example, it is set within context “location” with value /home/www-data/www.

The 13th directive is index, which defines files that will be used as an index. The value can be multiple file names separated by spaces. If a directory is requested (the request URI is ended with slash /), Nginx will try to find the files set by this directive respectively in the directory from root directive, and response with the first file found.

As we mentioned, the default directory specified by root directive for storing web files is mixed with the Nginx installation files as follow:

/usr/local/nginx/html

Obviously this is not a good practice, so as a best practice we will move them to the home directory of the dedicated account www-data (/home/www-data).

You may run below two commands to move the default folder of Nginx web files to the home directory of “www-data” account, rename the folder to “www”, and change the owner and owner group of this folder to “www-data”:

mv /usr/local/nginx/html /home/www-data/www
chown -R www-data:www-data /home/www-data/www

After modifying the configuration, you may run below command to test. If you see the word successful, it means the configuration is OK for Nginx running:

nginx -t

6 Start Nginx

Although we can use nginx command to start Nginx directly, in order to make it more stable (not stopped by system downtime or server maintenance), it is necessary to pass Nginx as a service to operation system, so Nginx can get restarted with system restart.

In CenOS, we use systemd (a system and service manager) to manage all services in system. To let systemd manage Nginx, we need to create a configuration file for it.

Use your favorite editor to create a configuration file, named nginx.service, under the directory below (here we use vi editor):

vi /etc/systemd/system/nginx.service

Copy the content below and save to the new file (for vi editor: press ESC + input :wq + press Enter):

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID

[Install]
WantedBy=multi-user.target

Let systemd reload the new configuration file:

systemctl daemon-reload

Now we can start Nginx service by command below:

systemctl start nginx

If any modification made to the configuration file, you may use command below to restart Nginx:

systemctl restart nginx

To check the status of Nginx service:

systemctl status nginx

If service status is Active: active (running), and no error or warning comes, everything is running fine. You may run below command to test:

curl 127.0.0.1

If you see words “Welcome to nginx!” within the HTML code, it means Nginx service is running fine. If port 80 is allowed from both VPC security group rules of your cloud server and firewall of your CentOS system, you should be able to access this page from web browser by the IP address of server as well.

At last, add Nginx as a service to start automatically with system boot:

systemctl enable nginx

So far, we have finished all steps on Nginx installation and configuration on CentOS.

7 Upgrade Nginx

To upgrade Nginx to a new version released in future, you only need to follow the step1, step2, step3, and step4 of this guide. Since configuration files will not be overwritten by the new installation, there is no need to update them.

8 Conclusion

After all steps above, there are files and information that should be useful for future maintenance. We listed them as below for your reference.

Path of Nginx configuration file:

/usr/local/nginx/conf/nginx.conf

Path of the configuration file of Nginx as system service:

/etc/systemd/system/nginx.service

If you have any problem to follow this guide, please leave a comment.


[1] Note that the term Request-URI is defined by the HTTP specification (RFC 2616, §5.1.2).

Leave a comment

Your email address will not be published. Required fields are marked *