CentOS7 / Debian 11源码编译nginx 1.22.0

CentOS7 / Debian 11源码编译nginx 1.22.0

编译前准备

找到下载链接

进入nginx官网:https://nginx.org,在它的右侧找到download,点进去。

找到“Stable version”,这就是最新的稳定版本,它提供一个linux和一个windows版本

CHANGES-1.22    nginx-1.22.0  pgp   nginx/Windows-1.22.0  pgp

而“Legacy versions”表示以前的版本,包括最新版本的前一个版本,也是在“Legacy versions”中。

使用wget下载

复制“Stable version”中的linux版(nginx-1.22.0)的链接,使用wget下载

wget https://nginx.org/download/nginx-1.22.0.tar.gz

解压并进入目录中

解压并进入目录中

tar -zxf nginx-1.22.0.tar.gz
cd nginx-1.22.0

查看目录中的文件

ls -l显示目录内容如下

total 832K
drwxr-xr-x 6 www www 4.0K Sep  6 15:15 auto
-rw-r--r-- 1 www www 310K May 24 07:59 CHANGES
-rw-r--r-- 1 www www 474K May 24 07:59 CHANGES.ru
drwxr-xr-x 2 www www 4.0K Sep  6 15:15 conf
-rwxr-xr-x 1 www www 2.6K May 24 07:59 configure
drwxr-xr-x 4 www www 4.0K Sep  6 15:15 contrib
drwxr-xr-x 2 www www 4.0K Sep  6 15:15 html
-rw-r--r-- 1 www www 1.4K May 24 07:59 LICENSE
drwxr-xr-x 2 www www 4.0K Sep  6 15:15 man
-rw-r--r-- 1 www www   49 May 24 07:59 README
drwxr-xr-x 9 www www 4.0K Sep  6 15:15 src

我们看一下auto目录

> ls -l auto
total 204K
drwxr-xr-x  2 www www 4.0K Sep  6 15:15 cc
-rw-r--r--  1 www www  141 May 24 07:59 define
-rw-r--r--  1 www www  889 May 24 07:59 endianness
-rw-r--r--  1 www www 2.8K May 24 07:59 feature
-rw-r--r--  1 www www  136 May 24 07:59 have
-rw-r--r--  1 www www  137 May 24 07:59 have_headers
-rw-r--r--  1 www www  411 May 24 07:59 headers
-rw-r--r--  1 www www 1020 May 24 07:59 include
-rw-r--r--  1 www www  768 May 24 07:59 init
-rw-r--r--  1 www www 4.8K May 24 07:59 install
drwxr-xr-x 11 www www 4.0K Sep  6 15:15 lib
-rw-r--r--  1 www www  18K May 24 07:59 make
-rw-r--r--  1 www www 3.9K May 24 07:59 module
-rw-r--r--  1 www www  38K May 24 07:59 modules
-rw-r--r--  1 www www  136 May 24 07:59 nohave
-rw-r--r--  1 www www  26K May 24 07:59 options
drwxr-xr-x  2 www www 4.0K Sep  6 15:17 os
-rw-r--r--  1 www www 8.7K May 24 07:59 sources
-rw-r--r--  1 www www  120 May 24 07:59 stubs
-rw-r--r--  1 www www 2.0K May 24 07:59 summary
-rw-r--r--  1 www www  394 May 24 07:59 threads
drwxr-xr-x  2 www www 4.0K Sep  6 15:15 types
-rw-r--r--  1 www www  26K May 24 07:59 unix

其中cc目录是用于编译的,还有lib库,os目录是对所有的操作系统进行判断的。其它的文件都是为了在configure脚本执行的时候,去判定Nginx支持哪些模块,当前操作系统有什么样的特性可以供Nginx使用。


  • CHANGES是英文版本的更新日志,而CHANGES.ru是俄文版的更新日志(Nginx作者是俄罗斯人)。
  • contrib目录中的vim目录,可让vim打开nginx配置文件时,能有高亮语法显示效果,而不是一版黑底白字,方法:
sudo cp -r contrib/vim/* ~/.vim/
  • conf目录:是默认的配置文件
  • html目录:是默认的两个文件,一个index.html,一个50x.html
  • man目录:是nginx帮助文件:man nginx.8可打开帮助
  • src目录就是nginx源码了

编译

# debian/ubuntu
apt update -y
apt install -y wget
apt install -y gcc
apt install -y bzip2
apt install -y make
apt install -y perl

# centos7
yum update -y
yum install -y wget
yum install -y gcc
yum install -y bzip2
yum install -y make
yum install -y perl
yum install perl-IPC-Cmd
yum install perl-Data-Dumper

查看编译选项

在前面解析的nginx目录中有个configure,我们运行它

./configure --help

它的参数里边主要分为几个大块:

  • 第一类,确定Nginx执行中,它会去找哪些目录下的文件作为它的辅助文件。比如需要动态模块,此时--modules-path=PATH就会产生作用。如果没有任何变动的话,只需要指定--prefix=PATH这个参数就可以了,所有的其它的文件都会在prefix指定的目录下面建相应的文件夹;
  • 第二类,主要是确定使用和不使用哪些模块,--with-开头的,如果你编译的时候不添加该模块,则它默认不会被编译进去,--without-开头的,说明它默认是会被编译进去的,如果你不想编译其中某个模块,你就用--without-来排除它;
  • 第三类,指定了Nginx编译中需要的一些特殊的参数,比如用gcc编译的时候,需要加一些什么样的优化参数,或者说需要打印dubug级别的日志是。

参考编译项:我们试着执行以下命令以检查编译环境是否准备好了,特别注意openssl和pcre我们是指定当前目录下对应的源码,所以你要你机器上对应的文件夹是什么名称,别直接复制我的,不然肯定报错

./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-openssl=./openssl-openssl-3.0.6 \
--with-pcre=./pcre2-10.40 \
--with-pcre-jit \
--with-ld-opt=-ljemalloc \
--with-stream \
--with-stream_ssl_preread_module \
--with-http_secure_link_module

上边的命令运行后,首先它会报这个错

checking for --with-ld-opt="-ljemalloc" ... not found
./configure: error: the invalid value in --with-ld-opt="-ljemalloc"

安装依赖

知道了编译依赖后,我们就可安装依赖了。

安装jemalloc依赖:在--with-ld-opt=-ljemalloc这个编译选项中,ld是个命令,man ld可以查到它的意思是“linker”,中文翻译为“链接器”,链接器是用于把目标文件链接起来生成可执行文件。

这里ld-opt就是“链接器选项”,-ljemalloc其中的-l表示library,而jemalloc才是真正要连接的一个库的名称,它是一个开源内存管理工具(github)。

malloc其实是memory allocation的缩写,就是说它是一个内存分配管理工具,用它来管理nginx的内存分配,可以优化nginx对内存的使用,事实上这个工具还可以用来管理mysql等很多软件(只要那些软件支持用jemalloc来管理),至于为什么要叫jemalloc,这只是个项目名称,可能只有作者才知道。

要使用jemalloc,要先编译安装jemalloc

# 下载jemalloc
wget https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2

# 解压
tar -jxvf jemalloc-5.3.0.tar.bz2

# 进入解压后的文件夹
cd jemalloc-5.3.0

# 编译安装jemalloc
./configure
make && make install

# 这一步看情况,有可能local.conf本来就已经存在/usr/local/lib了(lib也有可能是lib64,自己看着来)
echo '/usr/local/lib' >> /etc/ld.so.conf.d/local.conf

# 这是一个命令,用于配置动态链接库运行时的绑定(相当于安装了个新的东西,要绑定一下)
ldconfig

安装zlib依赖:有些系统不带zlib,需要安装zlib,--with-http_gzip_static_module选项需要使用(gzip压缩用)

#redhat/centos
yum install -y zlib zlib-devel

# debian/ubuntu
apt -y install zlib1g zlib1g-dev

如果没有zlib安装,会报以下错误

./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using –without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using –with-zlib= option.

尝试configure

./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-openssl=./openssl-openssl-3.0.6 \
--with-pcre=./pcre2-10.40 \
--with-pcre-jit \
--with-ld-opt=-ljemalloc \
--with-stream \
--with-stream_ssl_preread_module \
--with-http_secure_link_module

结果如下

Configuration summary
  + using PCRE library: ./pcre2-10.40
  + using OpenSSL library: ./openssl-OpenSSL_1_1_1n
  + 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"

现在虽然不报错了,但是要看一下这三个,其中zlib前面我们已经用包管理器(apt/yum)安装了,而PCRE和OpenSSL是依赖于当前文件夹下对应的源码,所以一方面,我们需要在nginx文件夹下放置pcre和openssl的源码文件夹,另一方面,需要分别编译安装pcre和openssl

+ using PCRE library: ./pcre2-10.40
+ using OpenSSL library: ./openssl-OpenSSL_1_1_1n
+ using system zlib library

编译openssl和pcre

安装openssl依赖:
openssl在这里,用wget下载后解压,进入目录,然后用以下命令编译安装

# 不安装会报:Can't locate FindBin.pm in @INC (you may need to install the FindBin module)
apt install -y perl

wget https://github.com/openssl/openssl/archive/refs/tags/openssl-3.0.6.tar.gz
tar -zxvf openssl-3.0.6.tar.gz
cd openssl-openssl-3.0.6
./Configure --prefix=/usr/local/openssl linux-x86_64
make && make install

如果是自己编译的,需要设置符号链接到/usr/local/bin/,这样就添加到环境变量了

ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl

直接输入openssl回车运行,应该会报错

./openssl: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory

上边的报错是因为找不到动态链接库,我们添加一下就行

echo '/usr/local/openssl/lib' >> /etc/ld.so.conf.d/local.conf
# 但有时候也可能是lib64,你自己看你电脑上/usr/local/openssl/文件夹下有什么就写什么
echo '/usr/local/openssl/lib64' >> /etc/ld.so.conf.d/local.conf
# 再运行一下这个ldconfig,相当于配置文件更新了,要重新加载一下
ldconfig

# 如果你前面的Configure中没有添加--prefix,那么libssl.so.3文件会在/usr/local/lib64/目录中,
# 我们可以直接用ldconfig来指定这个目录
ldconfig /usr/local/lib64/

其中/usr/local/openssl/lib就是openssl动态链接库的路径,如果你不知道在哪而,直接全局搜索吧

sudo find / -name libssl.so.3

查看openssl的版本,要用openssl version,它即不是用-v,也不是--version,也不是-V,而是没有杠,直接version,我这里编译的是1.1.1k,所以没错

> openssl version
OpenSSL 3.0.6 11 Oct 2022 (Library: OpenSSL 3.0.6 11 Oct 2022)

如果没安装openssl,会显示如下报错

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using –with-openssl= option.


安装PCRE库依赖:PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括perl兼容的正则表达式库。

pcre源码在这里,用wget下载后,解压并进入文件夹,然后开始编译(当然你也可以指定一下--prefix=/usr/local/openssl)

# 配置编译环境,检查编译依赖是否已存在等等,不指定参数,默认安装到/usr/local/bin/下
./configure

# 编译并安装
make && make install

安装好之后,使用以下命令可查看安装的三个可执行文件

> ls -lrt /usr/local/bin/
-rwxr-xr-x 1 root root    63880 Sep  6 14:12 pcre2grep
-rwxr-xr-x 1 root root   133336 Sep  6 14:12 pcre2test
-rwxr-xr-x 1 root root     2175 Sep  6 14:12 pcre2-config

不过更方便的是直接安装,直接安装就可以去掉这个选项--with-pcre=./pcre-8.43,它会自动搜索(但这种方法有可能让nginx中写的正则不生效,比如我就遇到过rewrite里写正则不生效)

#redhat/centos
yum install -y pcre pcre-devel

# debian/ubuntu
apt -y install libpcre3 libpcre3-dev

没有安装pcre会报错:

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using –without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using –with-pcre= option.

开始真正编译nginx

把openssl、pcre、zlib、jemalloc等依赖全部安装好之后再运行一遍前面的编译安装命令

./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-openssl=./openssl-OpenSSL_1_1_1n \
--with-pcre=./pcre2-10.40 \
--with-pcre-jit \
--with-ld-opt=-ljemalloc \
--with-stream \
--with-stream_ssl_preread_module \
--with-http_secure_link_module

如果一切正常,到这里就完成了nginx的编译安装。

configure完成后,执行以下命令编译和安装

make && make install

# 当然也有可能是,gmake是gnu make的意思,一般make都是gmake的一个符号链接,这个看configure完成后的提示就行
gmake && gmake install

安装好的nginx在/usr/local/nginx/目录中,其中可执行文件在/usr/local/nginx/sbin/nginx,我们给它创建一个符号链接到/usr/local/bin/,这样就加入到环境变量中了,你就可以直接执行nginx命令了

ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx

编译安装完之后的操作

创建一个名为www的用户和www组(以下命令是创建www用户,但组会自动伴随创建)

useradd -s /usr/sbin/nologin -M www

创建用于放置网站源码、日志、缓存的目录(目录放哪儿是个人习惯,我这里是参考oneinstack的)

mkdir -p /data/wwwroot/
mkdir -p /data/wwwlogs/
mkdir -p /data/wwwcache/

# 修改所有者和所属组为www,以后放到/data/里的网站文件也都必须属于www用户和组
chown -R www:www /data/

如果你是用vim的,设置一下让vim支持nginx语法高亮

mkdir ~/.vim/
cp -r contrib/vim/* ~/.vim/

修改nginx配置文件

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

修改nginx.conf配置,直接把以下配置粘贴进去就行,主要就是http模块的最后有一个inlcude,包含中一个文件夹中的所有文件

user www www;
worker_processes auto;

error_log /data/wwwlogs/error_nginx.log crit;
pid /run/nginx.pid;
worker_rlimit_nofile 51200;

events {
    use epoll;
    worker_connections 51200;
    multi_accept on;
}

http {
    include mime.types;
    default_type application/octet-stream;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 1024m;
    client_body_buffer_size 10m;
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 120;
    server_tokens off;
    tcp_nodelay on;

    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    fastcgi_intercept_errors on;

    #Gzip Compression
    gzip on;
    gzip_buffers 16 8k;
    gzip_comp_level 6;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_proxied any;
    gzip_vary on;
    gzip_types
    text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
    text/javascript application/javascript application/x-javascript
    text/x-json application/json application/x-web-app-manifest+json
    text/css text/plain text/x-component
    font/opentype application/x-font-ttf application/vnd.ms-fontobject
    image/x-icon;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    ##If you have a lot of static files to serve through Nginx then caching of the files' metadata (not the actual files' contents) can save some latency.
    #open_file_cache max=1000 inactive=20s;
    #open_file_cache_valid 30s;
    #open_file_cache_min_uses 2;
    #open_file_cache_errors on;

    # 缓存
    proxy_cache_path /data/wwwcache/nginx levels=1:2 use_temp_path=off keys_zone=STATIC:200m inactive=24h max_size=1g;

    ########################## vhost #############################
    include vhost/*.conf;
}

上边的配置中,最后include了一个vhost目录中的文件,但这个文件夹是不存在的,我们需要创建创建vhost目录,用于放置网站配置

sudo mkdir /usr/local/nginx/conf/vhost/

vhost中的网站配置必须以.conf结尾,如果不以.conf结尾,则不会被使用,因为前面用的是(include vhost/*.conf;),所以你可以在后面添加个.bak来暂时让你不想使用的配置不生效

www.test.com.conf
www.test2.com.conf

创建systemd service文件,用于开机自启动,这里建议我们放到/lib/systemd/system/目录下,但我认为我们用户编译的应该放到/usr/lib/systemd/system/下比较好

vim /usr/lib/systemd/system/nginx.service

:set paste进入粘贴模式,然后按i进入插入模式,然后把以下内容粘贴进去,按esc退出粘贴模式,最后:x保存

[Unit]
Description=The NGINX HTTP and reverse proxy server
Documentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPost=/bin/sleep 0.1
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000

[Install]
WantedBy=multi-user.target

启动nginx

# 启动
systemctl start nginx
# 查看启动状态
systemctl status nginx
# 重启
systemctl start nginx
# 停止
systemctl stop nginx

# 检查配置文件是否出错
nginx -t

# 平滑重启nginx
nginx -s reload

参考:吃透 Nginx 编译安装过程

打赏
订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

CentOS7 / Debian 11源码编译nginx 1.22.0