[Nginx] Building Nginx from source on CentOS 7

贺靖
2023-12-01

深受这篇博客文章的影响,边学习边记录下这篇笔记;其中根据我自己的疑问点,较为细致的解释了各种初学者可能产生的问题,希望能对正在阅读的你有所帮助。
It’s worthing mentioning that I’ve drunk too many coffee when writing the background part, making it really hard to read.
You have my most sincere regretfulness.

Background

I first knew about Nginx when I was tinkering something to help me bypassing the network censorship. I remember there was this tutorial in the advanced section of which introduced the possibility of making utilities of nginx to better disguise the traffic.

I was too young, too dumb (still), too broke, and too eager to get YouTube videos played, so I ignored everything in that section.

Time flies, as I became a college student who’s unfortunately majoring software engineering, I found myself in an awful need of a WebDAV server (Thank you Zotero). I quickly realized that there are generally 2 web servers which can help me with it, Apache and Nginx. Since I just finished Computer Networks and 网络通讯程序设计 (it’s hard to find a equivalent course that is targeted solely at Linux proxy programming) that semester, I thought it would be a really good opportunity to actually finish what I have left off years ago.

It worked until Zotero yelled at telling that the SSL certificate was expired. Having forgotten everything about how I managed to make it work, I decide to redo the process and dig into everything that I have questions about this time.

What makes it even better is post-rock music that I’ll keep a journal too.

And that’s the story behind the words following, since I am still learning, there have to be problems and issues.

You can always reach me at
zhixuanqi at outlook dot com

Let’s roll?

Method

There are generally 2 ways to get Nginx on your server, one is to install pre-built releases form the usual package repos, and the other one is to build it from source.

  • installing Nginx making use of the package manager would be a relatively easier task, while building it from source would give you a granular access to control more aspects of the package, including custom packages and paths.

Install with Yum

sudo yum install nginx

see you later

Build Nginx from Source

Installing prerequisite packages

yum install wget
yum install gcc gcc-c++ kernel-devel make 
yum install pcre pcre-devel
yum install zlib zlib-devel
yum install openssl openssl-devel
yum install gd gd-devel
  • what are the -devel packages?

Downloading and Extracting Source File

  • find the latest stable version and download the file. In my case, it is 1.20;
wget https://www.nginx.org/download/nginx-1.20.0.tar.gz
tar -zxvf nginx-1.20.0.tar.gz
  • tar -zxvf means to unzip, extract, print the filenames verbosely; To learn more about tar you can always visit the man.

Configuring the Build

  • enter the nigix directory to configure the build

    ls
    nginx-1.20.0 nginx-1.20.tar.gz
    cd nginx-1.20.0
    
    • now let’s see what’s in the folder
    auto     CHANGES.ru  configure  html     man     src
    CHANGES  conf        contrib    LICENSE  README
    
    • the configure executable is used for further configurations in building, for example specifying the path to files and custom modules to build.

    • however, before digging into the detail, I think it’s time to learn about the [[Filesystem Hierarchy Standards]]. Since I really need to know why would the crowd believe it is be such a good idea to place certain files in certain places.

      • the top level directories we should pay attention to are
        • etc: host specific system-wide configuration files
        • bin: essential command binaries that need to be available in single-user mode;
          • e.g. cat, ls, cp;
        • var: Variable files: files whose content is expected to continually change during normal operation of the system, such as logs, spool files, and temporary e-mail files
        • sbin: essential system binaries
          • e.g. fsck, init, route
        • usr: Secondary hierarchy for read-only user data; contains the majority of (multi-)user utilities and applications; note that there are very similar directory under /usr to the ones under /; The difference is that the files under usr are read-only user data.
    • A common configuration

    ./configure --prefix=/var/www/html --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --with-pcre  --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-http_ssl_module --with-http_image_filter_module=dynamic --modules-path=/etc/nginx/modules --with-http_v2_module --with-stream=dynamic --with-http_addition_module --with-http_mp4_module --with-http_dav_module
    
    • you can read about the full possible flags the arguments and list here
    • it’s worth noticing that by executing the previous command you would:
      • include ngx_http_ssl_module, which provides the necessary support for HTTPS
      • include ngx_http_image_filter_module, which can transform images in JPEG, GIF, PNG, and WebP forms.
      • include ngx_http_v2_module, which provides support for HTTP/2
      • include ngx_stream_core_module, which provides generic TCP/UDP proxying and load balancing.
      • include ngx_http_addition_module, which is capable of adding text before and after a response.
      • include ngx_http_mp4_module, which provides pseudo-streaming server-side support for MP4 files.
        • to know about what is [[pseudo-streaming]], read doc
      • include ngx_http_dav_module, which is intended for file management automation via the WebDAV protocol. The module processes HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY, and MOVE.
        • and this is actually one of the reasons why I first got into nginx
        • doc here
  • You would see the briefing once the configuration completed without any problem
    ![[Pasted image 20220513030559.png]]

  • A makefile would be generated for compilation.

Compiling the Makefile

make
make install
  • to make sure that the installation was a total success, we can check by
nginx -v
  • a possible output would be something similar to:
nginx version: nginx/1.20.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/var/www/html --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --with-pcre --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-http_ssl_module --with-http_image_filter_module=dynamic --modules-path=/etc/nginx/modules --with-http_v2_module --with-stream=dynamic --with-http_addition_module --with-http_mp4_module --with-http_dav_module

Adding systemd service to manage Nginx

systemd is a system and service manager running at PID 1 and act as init system to start all the other services. It grants you many advantages compared to other similar tools and adding Nginx as a service would let you take control of it more easily.

  • systemd works with compartments in units. There are 11 different kinds of unit entities supported by systemd, including:
    • service: process
    • socket: IPC/network socket/file system FIFO controlled
    • target: used for grouping units and as well-known synchronization points during start-up
      • for example, network-online.target actively waits until the network is “up”, where the definition of “up” is defined by the network management software. Usually it indicates a configured, routable IP address of some kind. Its primary purpose is to actively delay activation of services until the network is set up.
    • and etc…
  • The syntax used is inspired by XDG Desktop Entry Specification. Each file contains several sections partitioned by [Section] marks. Each section contains several rule entries in key=value pairs.

Creating Unit File

  • In our case, we would register a service unit for Nginx. To do so, we need to create a systemd unit file ends in .service.
    ![[截屏2022-05-15 下午7.13.56.png]]
sudo vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • Common configurations would be made under the [Unit] section. You can read more about the background and arguments here;
  • Here’s what does the file do
    • [Unit] Section
      • A Description is a natural language sentence used to depict the functionalities of the service for human beings. It’s not supposed to be a simple repetition of the name of the service, nor a complex paragraph.
      • After key is specify the order of service initiation together with Before. In this case, nginx.service would not be start until syslog.target, network-online.target, remote-fs.target, and nss-lookup.target have been initiated.
      • The value followed by Wants configures (weak) requirement dependencies on other units. In this case, it means that nginx.service is dependent to network-online.target
        • I wondered what are the differences between After and Wants at this point, so I did some research online and found this.
          • Basically, After only specifies the order of the initiation but it wouldn’t vouchsafe that the units listed are 100% launched before this current unit. The only thing guaranteed is the order. However, the units listed after Wants are definitely initiated at the time when we’re trying to wake up the current.
      • [Service] section
        • you can try to check the man page. I really lost the interest in listing everything in detail here, sorry. This is actually the important part because you’ll have to make sure the paths are right. You can always use nginx -V to check the information you need.

Using systemd to manage Nginx

  • First, we need to stop nginx using
sudo nginx stop -s
  • Then boot it up and check it’s status using systemctl
sudo systemctl start nginx
sudo systemctl status nginx -l
  • It is possible that you would see a log entry like this:
    ![[截屏2022-05-16 上午1.21.20.png]]
  • Don’t panic if you have already made sure that this is the path to the actual .pid file. This appears to be a well-known bug because systemd and nginx are having a “race” problem where systemd is expecting the .pid before nginx actually got to start to generate it.
    • The workaround here is:
      mkdir /etc/systemd/system/nginx.service.d  
      
      printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf  
      
      systemctl daemon-reload
      
  • We should be working fine by now.

Enabling Nginx on boot

sudo systemctl enable nginx

by doing so, systemd would create a symlink for nginx.service;

Discussion

Building up this WebDAV server again became something more than just a daring experiment, but a tumor I’ll have to deal with. It’s like the plug which has stuck every other tasks I have at this point. I can not focus on any of them without having my Zotero library synced.

See Also

[1] linux - what does -zxvf mean in tar -zxvf ? - Stack Overflow
[2] How to Install NGINX Web Server on Ubuntu 21.04 (armanism.com)
[3] Dummies Guide to Setting Up Nginx - Michael Lustfield
[4] Firesystem Hierarchy Standard
[5] CentOS install nginx
[6] What are devel packages
[7] Understanding Systemd Units and Unit Files
[8] systemd unit configuration
[9] Running Services After the Network is up

 类似资料: