为了避免一万个哈姆雷特的问题,本文如果没能帮你成功编译 Nginx,找我!微信:iyoooooooo。让我参与进来,正好查漏补缺,继续完善这篇文章。
APT 包管理器中的 Nginx 版本一般都比较旧,有些新特性无法使用,而且默认提供的功能并不能满足诸如 HTTP2 等需求,所以很大概率是要根据实际需要从源码编译 Nginx 的。
本文 针对 HTTP 或反向代理服务 去编译 Nginx,除了 保留 Nginx 的默认功能 外,还 扩展了一些功能,
- HTTPS;
- HTTP2;
- Certificate Transparency 策略证书;
- Brotli;
还有一些可选功能,见 “配置 Nginx 构建规则” 部分。
本文 专注在单机环境,满足个人网站、学习、原型、物联、轻量 IO 型的需求,诸如静态网站、动态网站、开放接口服务等部署涉及到 Nginx 的部分,都可以使用这篇文章来编译、安装 Nginx。”搭建 Nginx 集群” 部分请看下回分解。
只要不是天天使用 Linux,难免对一些操作不熟悉,所以本文会为每项操作提供尽可能详细的指南、描述。
如果你现在就有一台全新的 VPS,直接按照下文开始一步步操作即可。
更新系统
系统权限:在 root 用户下完成操作。如果是在非管理员权限的账户下操作,记得给每项操作带上
sudo指令前缀。
安装任何工具前,先更新(apt update)包软件源,再把已经安装的包都更新(apt upgrade -y)一下。这应该是个习惯,且是个好习惯。
通过包管理器安装必要环境
在 root 用户下完成操作。如果是在非管理员权限的账户下操作,记得给每项操作带上
sudo指令前缀。
构建 Nginx 需要先安装(apt install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev libgeoip-dev)些必备环境。
准备好 “ngx_brotli” 源码
系统权限:不要求一定要在管理员账户下操作。本文设定在非管理员账户下操作。
这是让 Nginx 支持 Brotli 压缩算法的模块。
登录服务器后,确定在当前账户根目录下,下载 “ngx_brotli” 源码,成功下载后,进入 “ngx_brotli” 根目录,将子项目更新下来。最后,切换到当前账户根目录准备其它模块源码。
为了方便、快速,将上述操作整理成清单,
cd ~git clone https://github.com/google/ngx_brotli.gitcd ngx_brotligit submodule update --initcd ~
国内云平台下载 Github 上的项目可能会失败,并非一定会失败,但如果你碰到了一直失败的情况,那么就在能科学上网的本地环境下把这个源码下载下来(Linux、Unix 系统环境依然是跟着上述操作,Windows 系统环境下就是路径写法不同),额外就是需要将它压缩了,建议使用 “tar” 或者 “zip”,这里使用 “tar”(tar -czvf ngx_brotli.tar.gz "替换成 ngx_brotli 文件夹的绝对路径"),再通过 FTP 工具传输到服务器上指定账户根目录解压缩(tar -xzvf ngx_brotli.tar.gz)。
准备 “ngx-ct“ 源码
系统权限:不要求一定要在管理员账户下操作。本文设定在非管理员账户下操作。
这是让 Nginx 支持 Certificate Transparency 策略证书的模块。
登录服务器后,确定在当前账户根目录下,下载 “ngx-ct” 源码,下载的文件是个压缩文件,先解压它,解压后的文件夹名称叫做 “nginx-ct-1.3.2”,重命名成简易的形式以方便编译 Nginx 源码时使用。
为了方便、快速,将上述操作整理成清单,
cd ~wget -O ngx-ct.zip -c https://github.com/grahamedgecombe/nginx-ct/archive/v1.3.2.zipunzip ngx-ct.zipmv nginx-ct-1.3.2 ngx-ct
准备 OpenSSL 源码
系统权限:不要求一定要在管理员账户下操作。本文设定在非管理员账户下操作。
这是实现 HTTPS 功能的加密模块。
登录服务器后,确定在当前账户根目录下,下载 “openssl” 源码,下载的文件是个压缩文件,先解压它,解压后的文件夹名称叫做 “openssl-3.0.7”,重命名成简易的形式以方便编译 Nginx 源码时使用。
为了方便、快速,将上述操作整理成清单,
cd ~wget -O openssl.tar.gz -c https://www.openssl.org/source/openssl-3.0.7.tar.gztar zxf openssl.tar.gzmv ~/openssl-3.0.7 ~/openssl
OpenSSL 3.0 是 OpenSSL 的最新主要版本,也是一个长期支持 (LTS) 版本。之前的 LTS 版本(1.1.1 系列)也可用并支持到 2023 年 9 月 11 日。所有旧版本(包括 1.1.0、1.0.2、1.0.0 和 0.9.8)现在都不再受支持,应该不被使用。
准备 Nginx 源码
系统权限:不要求一定要在管理员账户下操作。本文设定在非管理员账户下操作。
登录服务器后,确定在当前账户根目录下,下载最新 “nginx” 源码,下载的文件是个压缩文件,先解压它,解压后的文件夹名称叫做 “nginx-1.23.2”,这里不需要重命名它,直接切换到这个文件夹的根目录即可。
为了方便、快速,将上述操作整理成清单,
wget http://nginx.org/download/nginx-1.23.2.tar.gztar zxvf nginx-1.23.2.tar.gzcd nginx-1.23.2
配置 Nginx 编译规则
系统权限:不要求一定要在管理员账户下操作。本文设定在非管理员账户下操作。
在开始构建 Nginx 前,需要设定下构建规则,遵循 “优先保留默认配置,仅对关键部分定制” 的原则。紧跟着上一步,此时应该在 ~/nginx-1.23.2 文件夹的根位置,可以操作 pwa 指令检查一下。直接执行下述指令,
./configure --add-module=../ngx_brotli --add-module=../ngx-ct --with-openssl=../openssl --user=nginx --group=nginx --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_realip_module --with-http_geoip_module --with-http_slice_module --with-http_stub_status_module --with-http_degradation_module
--add-module=../ngx_brotli --add-module=../ngx-ct --with-openssl=../openssl 这部分目的是关联之前准备的必要模块源码。
“ngx_brotli”、“ngx-ct”、”openssl“、”nginx-1.23.2“ 文件夹都在用户根目录,即:
~
|- ngx_brotli
|- ngx-ct
|- openssl
|- nginx-1.23.2
但当前工作位置在 ”nginx-1.23.2“ 文件夹根目录中,所以使用 ../ 相对路劲指向 “ngx_brotli”、“ngx-ct”、”openssl“。
--user=nginx --group=nginx 这部分设置非特权用户的名称,默认是 “nobody”,为了增强辨识性,改名为 “nginx”。
--with-file-aio --with-http_ssl_module --with-http_v2_module 这部分启用几个 Nginx 内置但未默认启用的功能,它们对于当前文章而言时必须的。
--with-http_gzip_static_module --with-http_gunzip_module --with-http_realip_module --with-http_geoip_module --with-http_slice_module --with-http_stub_status_module --with-http_degradation_module 这部分同样是启用几个 Nginx 内置但未默认启用的功能,但这它们对于当前文章而言是可选的。
日志、缓存之类的路径都采用默认的,
- Nginx 可执行文件的位置就在
/usr/local/nginx/sbin/nginx这里; - 配置文件在
/usr/local/nginx/conf这里; - 主要错误、警告、诊断、锁、请求日志、进程 ID 文件都在
/usr/local/nginx/logs里; - 静态资源目录都在
/usr/share/nginx/html这里; - 各类缓存目录也会在
/usr/local/nginx里,执行ls /usr/local/nginx可快速查看,这类文件件名都会带个 “_temp” 后缀; - 安装 nginx 动态模块的目录在
/usr/local/nginx/modules这里;
发现没,所有路径的基础路径都是 /usr/local/nginx,如果要修改,可以通过设置 --prefix=路径 参数(父级路径,默认是 /usr/local/nginx)统一修改他们的,没有特殊需求的情况下,没必要修改。修改了之后,接下来的操作,但凡包含 /usr/local/nginx 路径的都得修改。
从 Nginx v1.9.11 开始,有 2 种方式使用额外的模块,本文选择将它们集成编译,而非编译成可单独动态加载的独立模块,因为目前官方只有几个模块支持动态加载,第三方模块需要自身升级支持才可编译成动态模块,支持加载动态模块的麻烦胜过好处。待生态支持较好了,再优先使用 “加载动态模块” 方式,到时候也会更新到本文中。
编译、安装 Nginx
系统权限:部分操作需要管理员权限。本文设定在非管理员账户下操作。
紧跟着上一步,此时应该在 ~/nginx-1.23.2 文件夹的根位置,可以操作 pwa 指令检查一下。
上一步中 Nginx 的构建规则已配置好,但系统中还没有名为 “nginx” 的用户、工作组,先创建它们,之后就可以开始构建了,构建成功后直接安装即可。
为了方便、快速,将上述操作整理成清单,
sudo groupadd -f nginxsudo useradd -g nginx nginxmakesudo make installcd ~
如果本来就在管理员账户下,上述操作不需要 sudo 指令部分。
检测 Nginx 安装成功与否
系统权限:需要管理员权限。本文设定在管理员账户下操作。
如果当前不在 root 用户下,会发现检查(/usr/local/nginx/sbin/nginx -t)结果是失败的。
有多个原因,比如:日志路径(/usr/local/nginx/logs)、缓存路径(/usr/local/nginx)都在根用户权限的路径(/usr/local/nginx)下。但这些都不是关键,关键是:只有 root 进程可以监听低于 1024 的端口,而一般的服务器都会监听 80 或者 443 接口,它们都低于 1024。
所以,Nginx 只能运行在根用户名下。或者说,只要切换到根用户下,检查(/usr/local/nginx/sbin/nginx -t)结果就是通过的。
否则就需要修改 Nginx 涉及到的所有路径的权限,监听的端口号也不能低于 1024,这会变得极其麻烦,可执行性很差。
支持 nginx 全局化名
系统权限:需要管理员权限。本文设定在管理员账户下操作。
从源码构建、安装 Nginx 后,全局系统环境下没有 nginx 这个指令,需要修改(vim ~/.bashrc) Bash 配置文件,在最后添加PATH=/usr/local/nginx/sbin:$PATH,重载 Bash 会话即可。如果是 zsh 的话,就修改 “~/.zshrc” 文件,再重载会话。
支持以守护进程的方式操作 Nginx
系统权限:部分操作需要管理员权限。本文设定在管理员账户下操作。
维护系统难免重启,重启后 Nginx 是不会自己启动,要手动启动。每次重启服务器都需要重启一次,非常的麻烦。这时候可以利用守护进程解决这个问题。
创建(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=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
之后,还需要手动设置(systemctl enable nginx)为在系统引导时自动启用 Nginx。
如果修改了 "/lib/systemd/system/nginx.service",需要告知 systemctl,systemctl daemon-reload。
启动 Nginx
系统权限:需要管理员权限。本文设定在管理员账户下操作。
先让 Nginx 自检(nginx -t),自检通过的话,一般显示如下,
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
自检通过后可直接启动(systemctl start nginx),之后就可以在浏览器里输入 http://[替换成服务器的 IP] 浏览 Nginx 服务器提供的默认页面了。
本文不会赘述 Nginx 配置文件的部分,不过每次修改了配置文件后,都可以这样先自检再启动或重载 Nginx 服务。
顺利启动了,但 http://[替换成服务器的 IP] 无法访问
检查下防火墙是不是没配置 HTTP 流量可出可入。 这几个指令可以看系统里默认使用的是什么防火墙,
systemctl status firewalldsystemctl status ufw出现类似Unit firewalld.service could not be found.字样说明系统使用的不是指令中检测的防火墙。 假设系统默认使用 ufw 配置防火墙,这番操作后刷新http://[替换成服务器的 IP]即可访问,ufw allow httpufw allow httpsufw enable\ufw reload
重载 Nginx
系统权限:需要管理员权限。本文设定管理员账户下操作。
systemctl reload nginx
如果网站配置中包括缓存配置,重载前先清理缓存,也就是清空缓存目录,否则可能发生重载后网站没变化的问题。
停止 Nginx
系统权限:需要管理员权限。本文设定在管理员账户下操作。
systemctl stop nginx
查看 Nginx 进程状态
系统权限:需要管理员权限。本文设定在管理员账户下操作。
systemctl status nginx
卸载
系统权限:需要管理员权限。本文设定在管理员账户下操作。
- Nginx 可执行文件;
- 配置文件;
- 主要错误、警告、诊断、锁、请求日志、进程 ID 文件;
- 静态资源目录;
- 各类缓存目录;
- nginx 动态模块的目录;
…
这些文件、目录都要删除掉,但因为它们都在
/usr/local/nginx这个位置,直接执行rm -rf /usr/local/nginx指令即可。
/usr/share/doc 位置可能会有 Nginx 的帮助文档,如果存在,也需要将它删除。
检查(grep '^ubuntu' /etc/passwd 或 id nginx)目前系统里有没有 “nginx” 用户,有的话也得清除(sudo deluser --remove-home nginx)掉,还得检查(getent group nginx)是否还有 “nginx” 分组,有的话也得清除(sudo groupdel nginx)掉。
如果为 Nginx 创建了守护进程,删除相关文件(rm -rf /lib/systemd/system/nginx.service)。
到这里就把 Nginx 卸载干净了,一般这时候会重启系统(systemctl reboot),确保内存中不会残留。
结语
本文 针对 HTTP 或反向代理服务 去编译 Nginx,除了 保留 Nginx 的默认功能 外,还 扩展了一些功能。但是具体的 HTTP 服务、反向代理服务如何配置,并非本文偏重,且听下回分解。本文单一为了顺利从源码编译、安装 Nginx。
附言一
打算将我的笔记都以文章的形式发布出来,与大家分享,更多(80%)还是想交流,集思广益,另外也想结识些志趣相投的新朋友,好朋友,🫵🏼,我知道你就在那儿,快联系我吧!😬(微信:iyoooooooo)