
简介Nginx 1.22.0 Linux版源码压缩包面向运维工程师、后端开发及对Web服务器原理感兴趣的读者。Nginx以高并发、低内存占用著称常被用作反向代理、负载均衡和静态资源服务此版本为稳定分支适合新站点部署或学习研究。资源包共403个文件以C源文件207个和头文件98个为核心另含conf配置模板、Makefile编译脚本及辅助工具文件整体仅714KB便于快速下载与解压安装。已有3326人学习使用适合需要在实际环境中搭建Nginx服务、调整编译参数或阅读源码以排查问题的用户。通过本包可以拿到完整的Nginx 1.22.0源码目录结构结合官方文档可完成从配置到编译安装的全过程也可借鉴其中的模块划分和配置写法为定制化开发提供基础。1. 系统仓库里只有旧版nginx业务又点名要1.22.0解压安装是把版本控制权拿回手里的方案你在一台最小化安装的Linux服务器上准备部署Web服务执行apt install nginx后装到的是发行版仓库里那个年代久远的版本而你手里的配置、模块和第三方扩展针对的却是nginx 1.22.0 Linux版本。这种时候解压安装是我会采用的方案下载官方tar.gz包解压配置编译把指定版本装到指定目录全程不碰系统包管理器。它解决的是精确版本、自定义编译参数和多实例共存的问题适合刚接触Linux编译安装的新手也适合被仓库版本锁住的老运维。读完这篇笔记你会清楚从哪里拿包、configure参数怎么设、systemd怎么写以及我踩过的那些坑。2. 解压安装和包管理器安装的差别选型原理与适用边界2.1 为什么包管理器不一定能给你1.22.0用包管理器安装nginx本质上是检索发行版软件源里已经编译好的二进制包。软件源的维护者希望给用户一个稳定、可追踪的版本所以会把一个版本的nginx固化成系统标准之后只做安全补丁的小更新大版本常年不动。你执行apt install nginx或yum install nginx拿到的多半是一个旧的小版本例如1.14或1.16而你手里配置里引用的模块、头文件、编译参数很可能只匹配1.22.0。这种时候包管理器不给力解压安装就成了把版本锁到你想要的位置的办法。我用这个方案时一般出于三个判断。第一目标机的软件源同步滞后或者干脆是内网环境没有合适的仓库。第二项目文档明确写了必须使用nginx 1.22.0这个具体版本兼容性测试都按它做。第三我需要在编译阶段加入自定义模块或参数比如开HTTP/2、开stream。缺少这三个条件我会反过来建议使用包管理器因为手工会带来不必要的维护量。另外包管理器安装还会把文件分散到系统多个目录日志在/var/log/nginx配置在/etc/nginx二进制在/usr/sbin/nginx。你看着不直观卸载也不利落。解压安装只用一个prefix目录独立装一堆文件在里面删除时直接删目录这种“一个软件、一个目录”的做法对于喜欢可控的运维来说很舒服。我放一个简单的对比表在这里方便你一眼看出边界对比项包管理器安装解压安装源码tar.gz版本由谁决定发行版仓库你下载的官方包安装路径/usr、/etc分散放置prefix自定义目录依赖处理自动解析安装configure脚本检查并报错升级方式仓库同步小版本更新重新下载解压编译多实例需要改配置与共享二进制不同prefix天然隔离卸载包管理器统一管理直接删除prefix目录这里每一个差别都会左右你的运维方式。版本准确性、目录隔离性、多实例部署这三项是解压安装最明显的优势也是我回头选它的原因。2.2 解压安装的本质从tar.gz到configure、make、make install解压安装这个说法容易让人以为解压完就能直接跑。实际上一把tar.gz源码包的任务是解压、配置、编译、安装。我按顺序给你拆一遍工作链。tar -xzf nginx-1.22.0.tar.gz cd nginx-1.22.0tar -xzf把源码包解到当前目录。这里有两个细节一是要提前规划好工作目录我一般放/usr/local/src里避免源码包目录被随意改动二是解压后的目录名nginx-1.22.0带着版本号后续脚本定位路径时不要把它随便改成别的名字。接着configure脚本登场。它检查系统里有没有nginx需要的依赖比如正则库、压缩库、SSL库然后把用户指定的编译选项写进Makefile。configure执行成功后会生成Makefile和objs目录如果缺少依赖库它就停在出错的位置并给出明确提示。这其实是有用的反馈与其后面跑一半失败不如在配置阶段就拦下来。make命令负责按Makefile里的规则把源码编译成二进制生成的核心可执行文件在objs/nginx。最后make install把这套产物复制到--prefix指定的目录。这个流程的收益是过程可复现。你只要保留configure参数和相关依赖的安装记录在另一台相同系统上重跑一遍得到的nginx行为和版本完全一样。这对批量部署、灾备恢复都很友好。代价是要手动处理依赖库安装、版本升级和安全补丁运维提醒必须自己留意。你决定走这条路的时候等于同时接受这份维护责任。再补充一个容易被忽视的点make install不会自动初始化运行用户也不会生成让你开机关机时用的service脚本。这些自由裁量权都回到了你手上。所以严格说真正落地一个可用的nginx服务不是以make install结束而是以你写好systemd服务为终点。这个观点我会在第4章展开你现在只需要记住解压安装对于路径和进程管理的影响是全局性的。2.3 什么时候该用解压安装什么时候别用选型不是越复杂越好。如果你只要一台能跑nginx的Web服务器apt或yum一行命令解决后面升级安全补丁也省事。解压安装的适用面主要被我归纳成四个场景精确版本锁定、自定义编译参数、多实例或固定路径要求、以及需要用第三方模块的场合。四个场景里命中一个我就走源码包路线。反过来解压安装也有一笔显性成本每次升级都要重新下载、configure、make、make install而且你必须在测试环境里先跑一遍验证。依赖库变了configure可能报错目录结构变了systemd unit也可能失效。如果你没有这个重复劳动的准备或者项目里同时有多个依赖包需要手工维护我建议老老实实用包管理器。它最大的优点正是你越不想操心的部分它替你操心了。我的判断原则可以缩成一句话版本、路径、模块三项里有一项是硬性需求就走解压安装三项都能将就就走包管理器。实际上我在评估新项目时最先问的永远是这三点而不是直接看别人的安装教程。先把选型理由定下来后面才不会被具体的命令牵着走。这篇文章后面的所有命令都是为“确认要解压安装”的人准备的。3. 在Linux上用tar.gz装好Nginx 1.22.0下载、校验、配置、安装的最小步骤集3.1 下载与校验别急着解压先确认文件完整官方发布nginx时会在下载页同时放.tar.gz和对应的校验文件。我在第2章里提过下载地址通常位于官方下载目录tar包按版本号命名。拿到包之后第一件事不是解压而是校验文件完整性。下载过程中偶发的网络中断或存储问题可能让tar文件尾部缺一块解压时才会报错到那时候排查起来反而更折腾。wget https://nginx.org/download/nginx-1.22.0.tar.gz wget https://nginx.org/download/nginx-1.22.0.tar.gz.asc sha256sum nginx-1.22.0.tar.gz这里先下载源码包和PGP签名文件再用sha256sum生成一个本地哈希值。你不需要自己记住官方哈希值把本地生成的哈希值拿到可信环境里与官方公布的哈希对照就能判断文件是否完整。如果你的机器上装有gpg并且已经导入了官方发布密钥还可以用gpg --verify验证签名。验证签名比起单纯哈希对照更可靠因为它能同时证明文件来源和完整性。校验完成后再解压。这个习惯能避免后面读到的是被截断的源码包。你可能会觉得每次装都要多一步很烦但打包出问题时这一下能帮你省下半小时找错时间。养成固定动作后这条命令也要写进你的安装脚本里方便整套自动化回归。这个步骤里最大的坑是有人贪快直接从不明来源的镜像站下载结果文件被篡改或版本不对。我见过有人在镜像站拿到一个nginx-1.22.0.tar.gz解压后configure报出一堆奇怪错误最后发现是别人重新打包过的。所以下载地址尽量用官方目录装之前顺手做哈希校验这是给自己买的后悔药。3.2 configure参数三个必调和一个推荐编译安装最核心的部分是configure。参数不同装出来的nginx行为和依赖也就不同。初次安装时我一般会在这几个参数里做选择先保证能用再优化性能。cd /usr/local/src/nginx-1.22.0 ./configure --prefix/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream--prefix定义了安装根目录。后续生成的所有文件都在这个目录下比如sbin/nginx、conf/nginx.conf、logs/。这个参数的设置决定了卸载、升级和脚本定位路径的难易度。--with-http_ssl_module启用HTTPS支持只要你的站点要接TLS证书这个模块就必开。--with-http_v2_module启用HTTP/2在HTTP/2已经普及的今天它是高并发页面性能优化的重要选项。--with-stream让nginx能作为四层负载均衡器转发TCP/UDP流量这个模块不开的话后端TCP代理这类需求就没法直接实现。如果你运行nginx的用户不是root还推荐额外加一个参数把worker进程运行到固定用户上./configure --prefix/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --usernginx --groupnginx--user和--group指定worker进程运行身份。配置了这两个参数后nginx启动时会自动把master进程保留为rootworker进程切换到nginx用户从而降低权限过高带来的风险。这个用户需要事先用useradd创建如果你不打算在systemd服务里写User选项那么nginx.conf里就必须保持这两个参数和系统用户一致。configure执行成功后会生成Makefile并打印一段配置摘要。摘要里列出的关键项你要扫一眼比如“nginx path prefix”“modules path”“configure arguments”是否按预期。如果发现参数漏配现在重跑configure比后面重新编译代价小得多。我见过有人configure一遍后又想加--with-stream结果直接从头再来就是因为一开始没养成看摘要的习惯。3.3 make与make install编译完成的二进制怎么落到系统里configure成功后就进入编译阶段。nginx这个项目编译比较轻量但现代CPU多核环境下直接用make让它单线程跑就亏了我一般先看核数再并行编译。make -j$(nproc) make install$(nproc)会返回当前机器的CPU逻辑核数make -j按这个数字并行编译能把编译时间从几分钟压到几十秒。注意这里不要盲目加更大数字比如用-j32在小机器上会大量消耗内存编译时内存不足反而让进程被杀。make编译完成后同目录下会多出objs目录里面有一个可执行文件objs/nginx这就是编译产物。make install把这产物复制到--prefix指定目录同时会带上conf/、logs/、html/这三个默认目录。make install之后你的安装就算完成了。此时先不要急着做任何修改去检查一下prefix目录的信号。如果/usr/local/nginx/conf/nginx.conf存在说明安装链路是通的。这个步骤里最容易发生的问题是configure时给了--prefix但后续手动拷贝或软链接时又用了系统级路径最后启动的是系统里的旧二进制而不是你刚装好的1.22.0。所以在配置systemd之前我习惯先执行一次。/usr/local/nginx/sbin/nginx -Vnginx -V会在输出里打印编译参数和版本号。你确认能看到nginx/1.22.0字样就说明手头这个二进制是对的。官方源码包里包含的html目录只有默认的index.html和50x.html如果你需要自定义站点页面在后面配置阶段再改不要手工往里面塞文件免得与nginx内部逻辑互相干扰。安装到这里只完成了一半真正让服务跑起来的是下一步的启动与管理。4. 启动、停止与开机自启第一次装好后直接跑进程容易出问题4.1 安装完成后的第一次配置检查和启动前缀目录建好之后先别急着执行sbin/nginx而是先做配置检查。我踩过很多次直接启动后页面不可用的坑原因很多是配置文件里少了分号或路径写错。nginx给了一个很好的自检机制nginx -t。/usr/local/nginx/sbin/nginx -tnginx -t会读取conf/nginx.conf依次检查语法、路径、include模块等。如果输出显示syntax is ok那就可以启动如果报错它会精准指出文件和行号比启动后看日志省时间。注意执行这条命令时一定要用绝对路径调用你编译出的二进制因为PATH里的nginx可能是系统自带的那一个二者可能版本不一致。确认配置没问题后执行启动/usr/local/nginx/sbin/nginx这条命令以daemon方式启动本身不会阻塞终端。启动后nginx会在logs目录生成nginx.pid文件里面记录master进程的PID。这个文件对后续reload、stop等信号操作很重要。如果没有生成pid文件说明启动失败了这时要立刻去看logs/error.log而不是反复执行启动。一次启动失败通常还会留下端口占用、配置文件路径错误这类普通报错日志里的行号会直接指出问题在哪一段。我习惯在这个环节顺手验证一下端口监听ss -lntp | grep nginx如果看到LISTEN状态的80端口说明启动这一步已经通了。如果你的服务器上原本跑了其他Web服务这里会立刻暴露端口冲突所以先检查再启动能少走一段回头路。4.2 用systemd接管nginx避免启动后进程没人管有人喜欢直接在命令行里sbin/nginx完事但服务器重启后nginx不会自动拉起而且进程掉线后也没有守护。我通常的做法是给systemd写一个unit文件让它把nginx当成一个服务管理。这样开机自启、崩溃重启、日志清理都顺势解决。cat /etc/systemd/system/nginx.service EOF [Unit] Descriptionnginx high performance web server Afternetwork.target [Service] Typeforking ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s stop PIDFile/usr/local/nginx/logs/nginx.pid [Install] WantedBymulti-user.target EOF这个unit文件的核心是Typeforking。nginx启动时master进程创建worker进程后原本调用的主进程会退出把控制权交给后台的master。因此systemd必须知道真正的服务主进程PID在哪里否则它会误以为启动失败。PIDFile指定到logs/nginx.pid配合ExecStart就能让systemd正确追踪。填完文件后执行systemctl daemon-reload systemctl enable --now nginx systemctl status nginxdaemon-reload重新加载unit文件enable --now让服务开机自启并立即启动。status命令的active (running)状态和进程信息能确认守护关系生效。如果你在配置systemd之前已经手动启动过nginx这里会碰到端口占用的问题先用pkill或nginx -s stop关掉手动启动的进程再交给systemd管理。还有个常见的维护动作是reload。修改配置后执行systemctl reload nginx它会走ExecReload里的nginx -s reload比restart平滑因为不会中断现有连接。我一般修改完配置后先用nginx -t检查再reload这是最基本的流程。4.3 运行用户与日志目录权限出于安全考虑worker进程不应该用root跑。第3章里如果configure时加了--usernginx --groupnginx那么在启动前要先创建这个用户并给logs和html目录授权如果没有加configure参数nginx.conf里可以直接用user指令临时指定运行用户。需要坚持的是worker进程权限尽量低。我遇过一次误操作运行用户加载不出静态文件最后发现html目录的属主是root、权限没有放开给nginx用户。这种情况下页面会显示403而日志里只有权限拒绝的一行。所以创建完用户后我会习惯性执行useradd -r -s /sbin/nologin nginx chown -R nginx:nginx /usr/local/nginx/logs chown -R nginx:nginx /usr/local/nginx/html-r表示创建系统用户-s /sbin/nologin禁止该用户登录这两项都能收紧权限面。logs需要写权限html需要读执行权限。之后启动再观察error.log别再让一些无关紧要的警告绊住。这里要补充一个容易被忽略的点如果在configure阶段没有加--user参数实际上还是一个常见做法是直接在nginx.conf的顶部写user nginx;。但这个指令必须放在配置文件的全局段且nginx.conf里的启动身份优先级会覆盖configure参数。如果你在配置文件里写了user root那你前面费劲创建的普通用户就没有意义了。所以每次改权限后我都要确认nginx.conf和configure参数口径一致否则排查半天最后发现是权限逻辑冲突。5. 解压安装Nginx的五个常见坑与排查路径5.1 configure报错“the HTTP rewrite module requires the PCRE library”现象./configure执行到一半输出类似“the HTTP rewrite module requires the PCRE library”然后直接退出。原因nginx的rewrite模块依赖正则表达式库系统里没有安装开发头文件。很多最小化服务器默认不带libpcre-dev这类包configure脚本检查依赖时就会拦下来。解决在支持包管理的系统上安装对应开发包。在Debian系用apt install libpcre3-dev在RHEL系用yum install pcre-devel装完后再重新configure。如果你需要静态链接这个库可以在configure加--with-pcre路径指向源码包但这会多一步下载pcre源码的步骤普通场景下系统库就够了。这个报错出现时不要慌它只是检查依赖不会污染环境重新执行configure就能继续。5.2 启动后访问一直转圈先看error.log再看防火墙现象nginx启动成功进程在防火墙也放行了80端口但浏览器持续转圈页面迟迟加载不出来。原因很多时候不是端口问题而是nginx的error.log里已经写了权限错误或upstream连接不上。我在排错时先看日志而不是先关防火墙因为防火墙问题主要是现网干等而日志能直接告诉你后端拒绝、权限拒绝等真实信息。解决执行tail -f /usr/local/nginx/logs/error.log看最新几行定位真实消息。如果日志为空再用ss -lntp检查监听地址如果你的nginx.conf里把listen 80改成了listen 127.0.0.1:80外部当然访问不到这时curl 127.0.0.1能通curl 公网IP不通问题就在监听地址或云安全组而不是nginx本身。5.3 systemd启动超时Type写错导致管理器等不到主进程现象systemctl start nginx卡住不动然后又超时失败systemctl status显示状态为activating (start)而不是active。原因unit文件的Typeforking写成了Typesimple。systemd会认为启动过程是一个前台进程而nginx自己会让主进程变成后台进程导致管理器没法确认服务已经起来最后把自己等超时了。解决确认unit文件里ExecStart指向绝对路径Typeforking同时PIDFile路径和nginx.conf里的pid指令保持一致。改完文件必须systemctl daemon-reload再重启服务。这个坑在手工复制unit文件时特别容易出现因为网上模板五花八门不熟的人根本不会注意到Type这一行的作用。5.4 升级翻车新二进制换了但模块旧目录和配置残留现象从1.20.0升到1.22.0make install执行后启动nginx -V显示的还是一个旧编译参数或某些模块加载失败。原因make install只在全新安装时干净升级时它会覆盖二进制但不清理旧的动态模块也不处理旧配置里的注释差异。新版二进制和旧模块之间可能存在ABI不兼容加载时直接报错。解决升级前备份整个prefix目录执行cp -a /usr/local/nginx /usr/local/nginx.bak.$(date %F)然后重新make install执行后对比nginx -V输出如果你手动替换过conf目录升级后配置文件也可能不对应新版二进制。这是典型的解压安装翻车点。我通常会先在staging环境模拟一次升级再动生产因为生产上直接覆盖很容易让回滚变得手忙脚乱。5.5 403权限拒绝worker进程拿到文件却没有读取权限现象静态文件路径写的问题不大但浏览器访问出现403日志出现权限拒绝。原因configure时加了--usernginxworker进程以nginx身份运行但它对html目录或静态资源目录没有读权限。权限过紧是解压安装常见的副作用因为手工管理目录时很容易把属主留给root。解决用chown指定目录属主或者增加执行权限保持目录路径在nginx用户的访问范围内。同时确认nginx.conf里的user指令没有在全局段配置成别的用户否则与configure参数冲突时以配置文件为准容易造成权限错觉。排查这类问题时我会顺手用sudo -u nginx ls 目录来模拟worker进程的访问视角直接验证权限是否通。6. 装完Nginx 1.22.0后我习惯做的五个验证动作从curl到日志断言装完服务后我从来不会直接交付。先做一组低成本的验证动作确认它真正可用而不是“看起来启动了”。先看监听端口和进程ss -lntp | grep nginx ps -ef | grep nginx确认master和worker进程都在监听地址符合预期。然后用curl验证默认页curl -I http://127.0.0.1期望响应里出现HTTP/1.1 200 OK。这一步验证的是web服务器基本功能如果返回503或拒绝连接问题通常出在配置或权限上。再验证你安装的版本和编译参数/usr/local/nginx/sbin/nginx -V重点看输出里的nginx/1.22.0和--with-http_v2_module这类参数确认自己没取错二进制。然后检查错误日志里没有启动期残留tail -n 20 /usr/local/nginx/logs/error.log这条命令应该返回几行启动成功的消息或者干脆为空。如果看到大量连接拒绝就要回到第5章去对号入座。最后我会做一个小技巧把nginx.pid文件内容读出来和ps里的PID比对确认systemd追踪的进程没有错位。这五个动作加起来不到一分钟却能覆盖进程、版本、配置、日志、守护关系这几个最容易出错的地方。从第一次手工编译到现在我每次都坚持先验证再交付。这个习惯救过我很多次尤其在服务器重启后忘记处理日志目录权限时系统起来却默默报错只有这种小验证能及时发现。希望帮到你少走我走过的弯路。本文还有配套的精品资源点击获取