前言
Nginx 1.25.0 实验性地将 HTTP/3 的支持合并到 mainline 中,现在可以通过--with-http_v3_module
来开启对这一功能的加入,本文将手把手带你从源码开始编译一个可用于学习环境的 Nginx。
在阅读本文之前,你至少会基础的 Linux 指令,知道根目录下的每个文件夹的作用是什么,知道 Linux(或类 Unix)环境下的文件系统、文件权限等,知道 GNU 编译器套件,以及之前使用过面板现在想自己手动地从头来的读者。
准备
首先是操作系统的准备,学习 Linux 运维的你当然需要准备一个 Linux 的环境,那么对于初学者来说,我最推荐的系统是 Ubuntu Server,每个人都有自己的偏好,Debian 也是个不错的选择,但是相对来说 Ubuntu 遇到的问题会少一些,Debian 则更纯净,也很适合折腾。
本系列文章的工作都基于 Ubuntu 的最新长期支持版 22.04.3,你可以在你的物理机上以双系统的方式安装,或者使用虚拟机,更方便的话,你可以使用云服务器来完成。
Nginx 编译
终于来到正文内容,首先 Nginx 作为一个高性能的 Web 服务器,这里就不过多介绍了,因为它的使用广泛已经受到了很多运维工程师的青睐,而基于 Nginx 的许多衍生版本也会在后面的文章介绍,例如 openresty
,Tengine
等。从现在开始,我们从零编译原始版本的 Nginx。
截止这篇文章的发表,Nginx 的最新 mainline 版本是 1.25.2,在 1.25 之后,官方将 QUIC 分支的部分代码合并到了 mainline,正式支持了 HTTP3 协议,本文将加入 HTTP3 模块编译的支持,感受 HTTP3 的魅力。
准备源码
建立新用户
1
| sudo useradd -M -r -s /bin/false -c 'Web server' www
|
建立日志、缓存、配置文件等目录,并赋予权限
1
| mkdir /var/log/nginx /var/cache/nginx
|
更新系统并安装编译器套件
1
2
| sudo apt update
sudo apt install build-essential
|
首先准备必要的开发库,包括 pcre2
zlib
,以及openssl
,其中前两者使用包管理器安装,openssl
使用最新版源码,需要注意的是,Nginx 在 1.21.5 及之后的版本启用了默认 pcre2 的支持,所以在此使用 pcre2
1
| sudo apt install libpcre2-dev zlib1g-dev
|
建立一个工作环境,我们在/usr/local
目录下完成我们的工作
1
| mkdir /usr/local/src && cd /usr/local/src
|
然后将 openssl
下载下来,放到一个合适的位置,截止发文,最新版为 3.1.3
1
2
| wget https://www.openssl.org/source/openssl-3.1.3.tar.gz
tar zxf openssl-3.1.3.tar.gz
|
下载 Nginx 源码
1
2
| wget https://nginx.org/download/nginx-1.25.2.tar.gz
tar zxf nginx-1.25.2.tar.gz
|
配置 Makefile
1
2
| cd nginx-1.25.2
./configure --with-openssl=/usr/local/src/openssl-3.1.3 --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=www --group=www --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/usr/local/src/nginx-1.25.2=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
|
依照 CPU 核心数,多线程编译,我的测试在四线程下 2 分钟不到就跑完了
编译完成后,安装到系统
测试版本信息,若打印下面的内容,则说明编译安装成功
1
2
3
4
5
6
| $ nginx -V
nginx version: nginx/1.25.2
built by gcc 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
built with OpenSSL 3.1.3 19 Sep 2023
TLS SNI support enabled
configure arguments: --with-openssl=/usr/local/src/openssl-3.1.3 --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/usr/local/src/nginx-1.25.2=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
|
若想要守护运行,添加一条服务项到 systemd
,输入以下命令来给 Nginx 添加一个守护进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| cat > /etc/systemd/system/nginx.service << EOF
[Unit]
Description=nginx - high performance web server
Documentation=https://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
|
使用对应命令启动就行啦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 首先刷新 systemd 配置文件
sudo systemctl daemon-reload
# 设置开机启动并且立即启动
sudo systemctl enable nginx.service --now
# 关闭开机启动
sudo systemctl disable nginx.service
# 停止服务
sudo systemctl stop nginx.service
# 查看服务状态
sudo systemctl status nginx.service
|
虚拟主机
想要添加虚拟主机,需要修改一下主配置文件,并且建立一个存放虚拟主机配置文件的文件夹。
1
| mkdir /etc/nginx/conf.d
|
修改 /etc/nginx/nginx.conf
主配置文件,在 http
模块最后新加一行
1
2
3
4
5
6
7
8
9
| http {
server {
# 默认虚拟主机
# ...
}
# 新增下面这行
include /etc/nginx/conf.d/*.conf;
}
|
然后就可以在 /etc/nginx/nginx.conf
新增一个你的网站的配置文件,具体如何新建一个虚拟主机将会在后面的文章详细介绍。