离线安装nginx:rpm依赖集合与gcc编译链完整指南

发布时间:2026/10/14 20:16:16
离线安装nginx:rpm依赖集合与gcc编译链完整指南
简介面向Linux服务器运维、Java后端及网络受限环境下的部署人员这份离线安装包针对无法直接访问外网的问题集中整理了nginx及其编译链gcc所需的rpm依赖集合覆盖常见Linux发行版的安装需求。压缩包共4个文件以gz格式为主包含nginx源码包、gcc环境依赖包、nginx相关rpm包以及一份HTML安装说明文档整个压缩包仅62.15MB便于随身拷贝至目标服务器。资源目前已吸引1682人学习下载其核心价值在于省去逐台服务器联网搜索依赖及逐一尝试版本的繁琐过程降低因缺少依赖或版本不匹配导致的安装失败概率。尤为适合内网环境安装时可按说明完成gcc与nginx的部署并可通过与Tomcat等Java应用协同实现动静分离是提升离线部署效率的实用工具。此外讲解内容还涉及离线安装时的版本兼容性检查思路可帮助运维人员提前识别依赖冲突风险提高一次性部署成功率。1. 离线安装 nginx 的第一道坎gcc 与依赖 rpm 的合集能省多少事在断网、没外网的环境里离线安装 nginx是所有内网部署工程师绕不过去的第一道坎。我曾在某隔离项目现场遇到过服务器刚上架Java 后端包都就绪了yum install nginx 敲下去屏幕回给你的却是一行 Could not resolve host。折腾到后面才明白问题根本不在 nginx 本身能不能编译而在于 gcc、pcre、zlib、openssl 这一整串编译依赖没有现成的 rpm 可装。这份 nginx 离线安装 rpm 集合正是为了解决这个痛点——它把编译 nginx 所需的 gcc 工具链和依赖包收拢在一起让隔离 Linux 环境也能按标准流程完成源码编译安装。适合做过基础 Linux 命令、但第一次碰离线部署的运维和实施同学也适合需要自行搭建 Java 后端前置网关的开发者。2. 为什么这套 rpm 集合能装通依赖关系与版本匹配逻辑2.1 nginx 编译链的真正瓶颈gcc 与 glibcnginx 源码包本身很轻解压下来也就几个目录真正让你卡在原地的是编译它之前必须就位的工具链和库。./configure阶段检查的是头文件和库文件make阶段开始调编译器这两个阶段的报错风格完全不同configure 会明确告诉你缺哪个库make 阶段抛出的却经常是读不懂的编译器内部错误。在这条链路上gcc 是第一道闸门。最小化安装的内网服务器经常没有装 gcc你敲make会看到cc: command not found。而 gcc 并不是一个独立 rpm 那么简单它往下依赖 binutils汇编器和链接器、cpp预处理器、gmp / mpfr / libmpc编译期运算用的多精度库再往下还压着 glibc 和 libgcc。只要这条链上任何一环缺失或版本错位gcc 要么装不上要么装上后编译行为异常。我一般进场后会先看两样东西系统的/etc/redhat-release和 glibc 版本。原因很简单离线环境里最怕的不是缺包而是包与系统底子不匹配——比如在 glibc 2.17 的老系统上塞一套针对新版本 glibc 构建的 gcc rpm装的时候能过make 的时候再给你来一个 internal compiler error。这种问题定位起来特别像玄学实际上从一开始就该按系统的发行版大版本去匹配 rpm 集合。2.2 这套集合覆盖什么依赖清单与选型思路把离线编译 nginx 需要的东西拆开看可以分成三组编译工具链、库运行依赖、nginx 模块依赖。这套 rpm 集合常见编排方式是把工具链放一组库和 devel 包放一组nginx 源码包单独放。核心组件清单如下组件作用缺失时看到的现象gcc / gcc-cC、C 编译器make: cc: command not foundmake构建调度工具make: command not foundpcre / pcre-devel正则库支持 rewrite 模块configure: PCRE library not foundzlib / zlib-develgzip 压缩模块依赖configure: zlib library not foundopenssl / openssl-develHTTPS 与 TLS 支持configure: SSL modules require OpenSSLglibc / libgcc 等基础库系统运行底座上述任意工具装不上或运行崩溃这里的关键点很反直觉不仅要有运行时库pcre、zlib、openssl还必须要有对应的-devel包。devel 包提供编译时需要的头文件.h和未 strip 的库文件。很多初次做离线部署的人只装了运行库configure 依旧找不到头文件就卡在这一步不动了。版本选型我的习惯是系统越老rpm 集合越要挑“同代”版本。比如隔离现场是 glibc 2.17 的系统我宁可配 nginx 1.20.x 的源码也不上 1.25.x因为新源码对编译器标准要求更高老 gcc 下编译容易翻车。依赖集合也是一样x86_64 架构就只认 x86_64 的 rpm不要混 i686进场后发现架构不匹配当场重装整套依赖极其痛苦。这个“进场前先核对底子”的习惯能省下后面至少半天时间。注意内网机器上偶尔会有残留的半通 yum 源依赖解析时连外网超时反而搞出一堆半下载缓存。离线部署场景里rpm 逐个装是比 yum 更可控的路径前提是你手里的依赖集合是闭环的。3. 把 rpm 集合落到内网传输、安装到编译的全流程3.1 进场前先确认三件事系统版本、架构、已装包rpm 集合在 U 盘里或通过运维通道拷进内网后第一件事不是解压而是先摸清机器的底。三个命令就能完成cat /etc/redhat-release uname -m rpm -qa | grep -E ^(gcc|make|pcre|zlib|openssl)第一行看发行版大版本决定你该用哪一套 rpm第二行确认 CPU 架构是 x86_64 就只装 x86_64 的包别把 i686 混进来第三行看这台机器上已经装了哪些组件避免重复安装。参数说明rpm -qa是查询所有已装包grep -E ^(gcc|make|pcre|zlib|openssl)用^锚定包名前缀防止把 gcc-c 当 gcc 单包漏看也避免匹配到 util-linux 这类无关名称。如果输出里已经出现了 gcc 和 make就不必再重复装工具链直接跳到库和 devel 包那一步如果什么都没有就按顺序从基础链开始装。这一步在实际操作里最容易被跳过尤其是赶时间进场的时候。但跳过它的后果是装到一半发现 glibc 版本不匹配整套 rpm 安装中断回头还得重新核对系统底子。我的习惯是先把三行命令的输出贴到笔记里再开始下一步磨刀不误砍柴工。3.2 按依赖顺序逐层安装不要对 *.rpm 一把梭把集合拷进内网后最容易翻车的操作是rpm -ivh *.rpm。rpm 不像 yum 会自动解析依赖它只会按你指定的文件顺序逐个安装遇到“被依赖的包还没装”就直接报 Failed dependencies 并中止。一打*.rpm上去报错信息能滚满一屏你根本分不清该先装哪个。我一般按依赖层级分四批装顺序从最底层的基础库往上层工具链推cd /data/rpm_collection # 第一批系统底层库与头文件 rpm -ivh libgcc*.rpm glibc*.rpm kernel-headers*.rpm # 第二批编译器运行依赖 rpm -ivh mpfr*.rpm libmpc*.rpm gmp*.rpm # 第三批编译工具链 rpm -ivh binutils*.rpm cpp*.rpm gcc*.rpm gcc-c*.rpm make*.rpm # 第四批nginx 模块依赖 rpm -ivh pcre*.rpm pcre-devel*.rpm zlib*.rpm zlib-devel*.rpm openssl*.rpm openssl-devel*.rpm逻辑说明第一批解决的是系统运行底座第二批是 gcc 运行时依赖的多精度库第三批才是真正的编译器第四批是 nginx 编译要用的库和 devel 头文件。每一批成功后再进入下一批哪一批报错就说明对应依赖没闭环。参数说明-ivh表示 install安装加 verbose显示详细信息加 hash显示进度条。如果机器上已经有旧版本把-ivh换成-Uvh做升级比如系统自带 openssl 版本较低就用-Uvh openssl*.rpm覆盖升级。注意升级系统关键库之前最好确认新版本不会把系统已有程序拉崩拿不准时就先只装 devel 包。如果某一步还是报依赖缺失比如error: Failed dependencies: libmpc.so.3()(64bit) is needed by gcc-4.8.5-39.el7.x86_64这说明 gcc 需要 libmpc 提供的库文件但当前机器上没有。解决方法是回到集合里找到libmpc*.rpm先装上再回来装 gcc。这套报错是阅读理解题error 下面每一行都会告诉你“谁被谁需要”照着补就能继续。3.3 nginx 源码编译三步configure 参数怎么定、make 失败怎么看依赖齐了以后把 nginx 源码包解压出来就是标准的三部曲tar -xzf nginx-1.20.2.tar.gz cd nginx-1.20.2 ./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-stream make -j4 make install逐行逻辑说明第一行解压源码包第二行进入源码目录第三行 configure 检查头文件和库是否齐全并生成 Makefile最后一行用-j4并行编译编译完直接安装到--prefix指定的目录。参数说明--prefix/usr/local/nginx决定安装根目录后续的 nginx -t、nginx -s reload 都基于这个路径别乱改。--with-http_ssl_module启用 HTTPS内网环境即便当下不用也建议编上省得以后需求来了重新编译一遍。--with-http_stub_status_module自带连接状态页离线场景下没有监控工具靠它看活跃连接数非常实用。--with-stream开启四层 TCP/UDP 能力Java 后端做非 HTTP 协议透传时会用到。make 的-j4表示用 4 个并行任务编译CPU 核多的机器可以调成-j8内存小的机器建议-j2避免编译时内存被吃满。make 阶段最常见的报错是cc: error: unrecognized command line option -stdc11这意味着系统 gcc 版本偏老不认识 C11 标准选项。这种时候别去折腾 gcc 升级直接从源头换一个与系统代际匹配的 nginx 源码版本比如 1.18.x重新 configure 一遍通常就过了。编译完成后验证一下安装结果/usr/local/nginx/sbin/nginx -V输出里的 configure arguments 会完整列出你刚才传的所有编译参数这就是确认功能是否真编进去了的硬凭证不用靠猜。4. 离线安装常见问题排查五个现场与对应解法以下五条来自多个隔离项目现场的踩坑记录前四条是依赖和编译层面的问题最后一条是操作习惯问题每一条我都按现象、原因、解决三个步骤理一理照着对号入座就行。4.1 pcre-devel 装上了configure 仍报 PCRE library not found现象rpm -qa里明明能看到 pcre-devel./configure却还报 the HTTP rewrite module requires the PCRE library。原因最常见的是架构不一致系统是 x86_64装进去的 pcre 或 pcre-devel 却是 i686 版本configure 在默认库路径里找不到 x86_64 的头文件和库。另一种情况是只装了 pcre没装 pcre-devel缺少编译所需的 pcre.h 头文件。解决先看架构是否统一执行rpm -qa | grep pcre确认每个包的架构都是 x86_64。再看库和头文件是否真的落位执行ls /usr/lib64/libpcre* /usr/include/pcre.h。如果 libpcre 有而 pcre.h 缺失就是 devel 包没进系统回头补装 pcre-devel 即可。4.2 make 中途崩掉internal compiler error 与 gcc 版本错位现象依赖都装好了gcc 也能跑但 make 编译到一半报Internal compiler error: Segmentation fault或直接退出没有明确指向哪一行代码。原因多数情况是 gcc 版本与系统 glibc 底座不匹配典型例子是在老系统上硬装新版本 gcc。编译器内部报错信息没有指向源码问题的上下文看起来像黑匣子其实底子是版本代际问题。解决先把系统底子查清楚执行cat /etc/redhat-release和rpm -qa glibc确定大版本号再看gcc --version。如果 gcc 版本比系统发行版自带版本跨了太多代就换回与系统同代的 rpm 集合如果 gcc 和系统没问题再考虑编译内存不足用-j2降并发重试。4.3 SSL 模块编不出来openssl 头文件缺失与老版本问题现象./configure加上--with-http_ssl_module后直接报./configure: error: SSL modules require the OpenSSL library。系统里其实有 openssl 这个包nginx 却还是说找不到。原因系统自带的 openssl 通常只是软件运行时需要的那个库不附带开发头文件。configure 需要的是openssl/ssl.h和libssl.so这套开发文件没有 openssl-devel头文件就不存在。解决先确认 openssl-devel 是否安装执行rpm -qa | grep openssl。如果系统里的 openssl 版本本身太老而 rpm 集合里又没有能匹配的 devel 包就用源码方式让 nginx 内嵌编译 openssl在 nginx 源码目录的 configure 命令里加--with-openssl/path/to/openssl-1.1.1w让 nginx 自行编译一套 openssl。这条路要留足编译时间但能绕开系统库版本锁死的问题。4.4 bind() to 0.0.0.0:80 failed端口被占与防火墙联动现象nginx -t通过启动却报bind() to 0.0.0.0:80 failed (98: Address already in use)进程没有起来。原因内网老机器上经常还跑着 httpd 或者其他 web 服务80 端口已被占用。比这更隐蔽的是进程监听的端口可能没被占但防火墙或安全组根本没有放行 nginx 监听的新端口外部访问不通本地 curl 却正常。解决先定位占用者执行ss -lntp | grep :80看到占用进程后能停就停不能停就把 nginx 的 listen 改成 8080。改完端口后一定记得把防火墙和安全组策略同步放开对应端口。我的经验是改监听端口之后忘放行防火墙这种二次翻车出现的频率比第一次端口冲突还高。4.5 离线机上误用 yum半通源带来的依赖损坏现象内网机器上残留有部分 yum 源配置执行 yum install 后不是报网络超时就是装到一半中断再次用 yum 时提示缓存损坏或依赖关系被破坏。原因这种机器多半处于半联通状态yum 能连到源服务器但速度极慢或在超时后留下半截缓存把本地的 rpm 数据库搞乱。解决离线环境里没有十足把握就不要用 yum。我的操作习惯是先把/etc/yum.repos.d下的源全部改名禁用全程只走 rpm -ivh。如果一定要用本地源用createrepo生成 repodata 后指向file:///路径并禁用所有远程源。半通源的存在本质是把离线部署的确定性让给了外部网络而离线场景里确定性比便利性重要得多。5. 装完不等于跑稳验证、systemd 托管与 Java 后端反代配置5.1 用 nginx -t 和 curl 完成双确认编译安装完成不代表服务已经可用。启动前的验证我固定走三步行/usr/local/nginx/sbin/nginx -t /usr/local/nginx/sbin/nginx ps -ef | grep nginx curl -I http://127.0.0.1nginx -t 校验全部配置文件的语法输出 syntax is ok 和 test is successful 后再继续启动后用 ps 确认 master 进程和 worker 进程都在curl -I 取响应头只要看到HTTP/1.1 200就说明默认站点已经响应。注意本地 curl 通不代表外部能访问。内网机器的防火墙与安全组经常只放行固定端口如果外部连接超时先检查端口是否在放行名单里再启用 nginx。这一步的细节在于nginx -t 验证的是配置文件语法而不是网络通路两者是两码事分开确认才不会误判。5.2 systemd 接管解决重启后 nginx 不自动拉起离线环境下服务器经常面临计划内重启或断电恢复不把 nginx 交给 systemd 管理机器一重启nginx 就处于“进程全没了但服务管理里什么都没配置”的裸奔状态。我在现场会用下面的 service 文件[Unit] Descriptionnginx - high performance web server Afternetwork.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStartPre/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s quit PrivateTmptrue [Install] WantedBymulti-user.target保存后执行cp /tmp/nginx.service /etc/systemd/system/nginx.service systemctl daemon-reload systemctl enable nginx systemctl start nginx systemctl status nginx参数说明Typeforking表示 nginx 启动后主进程会进入 fork 模式systemd 需要 PIDFile 来确认主进程的 PID路径必须对应编译安装时--prefix下的 logs 目录。ExecStartPre在每次启动前先执行 nginx -t配置写错时服务直接起不来报错会明确指到配置文件哪一行。ExecReload和ExecStop都用 nginx 自带的优雅控制reload 不中断现有请求quit 会等 worker 处理完手头的连接再退出。这套配置还能顺便解决崩溃拉起问题前提是 systemd 的默认 Restart 策略跟上。如果要更保险可以在 [Service] 段加一句Restarton-failure让它因配置或端口问题退出时自动重启。离线机器没有外部监控时这个兜底机制能少跑不少路。5.3 Java 后端场景配置upstream 反代与 stub_status 观察离线部署里 Java 后端是高频场景比如一个 Java 应用监听 8080要求外网请求走 80 端口由 nginx 做反代。这时在 nginx.conf 的 http 块里加一段 upstreamupstream java_backend { server 127.0.0.1:8080 weight1 max_fails2 fail_timeout30s; keepalive 32; } server { listen 80; server_name _; location / { proxy_pass http://java_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }逻辑说明upstream 定义后端服务器组server 行里的127.0.0.1:8080是 Java 应用实际监听地址weight1表示权重为 1max_fails2表示连续失败 2 次就把后端标记为不可用fail_timeout30s是标记失效的窗口时间。keepalive 32让 nginx 与 Java 后端之间保持长连接减少频繁新建 TCP 连接带来的开销。proxy_set_header的四行很关键Java 应用拿不到客户端真实 IP 时排错会非常痛苦所以要把 Host、X-Real-IP、X-Forwarded-For 和 X-Forwarded-Proto 都透传过去。如果 Java 应用里有依赖来源 IP 做判定的逻辑缺了这几行就是事故现场。再补一个常见调优Java 后端某个接口是长耗时任务超过 nginx 默认 60s 的proxy_read_timeout就会在客户端看到 504。这种场景在 location 块单独加一行proxy_read_timeout 300s;这个参数按业务特征单独调不要全局放开全局放开容易掩盖上游服务的真实健康问题。离线环境没有外置监控时观察 nginx 状态最简单的方式是编译时带上的 stub_status 模块location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }配置好后用curl http://127.0.0.1/nginx_status就能看到 Active connections 和 Reading/Writing/Waiting 三项数据。allow/deny 限定只有本机能看防止内网扫描把状态页暴露出去。6. 自己生产 rpm 离线包yumdownloader 与依赖闭环验证拿到别人做好的 rpm 集合省事但以后如果还要在现场装别的组件比如 keepalived 或 openresty就得学会自己收集依赖。在能联网的机器上用 yumdownloader 可以很方便地生产一份离线包mkdir -p ~/rpm_pack cd ~/rpm_pack yumdownloader --resolve --destdir~/rpm_pack make gcc gcc-c pcre-devel zlib-devel openssl-devel--resolve参数会自动解析并下载所有依赖包--destdir指定输出目录。如果没有 yumdownloader先yum install -y yum-utils装上。下载完成后要验证依赖闭环我一般这样检查rpm -qpR *.rpm | grep -v rpmlib | sort -u /tmp/requires.txt while read req; do if ! rpm -qp *.rpm | grep -q ^${req}; then echo missing: $req fi done /tmp/requires.txt这段脚本把目录里所有 rpm 的依赖项列出来再用目录内所有 rpm 的 provides 做匹配打印出缺失项。执行结果为空说明依赖闭环成立如果打印出 missing就回到联网机器补下载对应 rpm。这套流程我每次进内网前一天都会跑一遍把生成的 rpm 包和 nginx 源码放在同一个 tar 包里进场装完再按第 4 章的清单逐项核对。从那以后我每次做离线部署都强制走一遍“先在联网机器上把依赖装到本地模拟目录验证闭环后再打包进场”的流程早期那种进场后才一层层找依赖、把现场当测试机的日子彻底翻篇了。希望这套方法也帮到你。本文还有配套的精品资源点击获取