简介:面向网络受限环境下的Linux服务器运维人员,这份离线安装包将gcc编译环境和Nginx服务所需的rpm依赖集合统一打包,并附有清晰安装指引,可在无外网的数据中心、内网隔离区或临时环境中快速完成部署。包体共4个文件,3个gz压缩包分别对应gcc编译工具链、Nginx运行时依赖与Nginx源码,另含1个html文档,按顺序说明依赖安装、配置要点和启动验证,整体约62.15MB,结构简洁、便于分发。目前已有1682人学习下载,特别适合需要为Java后端搭建反向代理或静态文件服务的场景,无论是初级运维照着操作,还是老手批量部署,都能省去逐一下载缺失依赖的烦恼。借助该资源还能有效规避版本不兼容导致的安装失败,在无网条件下快速获得高性能Web服务能力。
1. nginx离线安装:为什么绕不开这套rpm包集合
在内网服务器上部署nginx,最磨人的不是nginx本身,而是它背后的编译依赖。很多环境连外网都出不去,yum install直接报错,这时候如果手里没有一套完整的离线rpm包,整个部署就会卡死在第一步。本文说的就是这件事:把gcc、make、pcre、zlib、openssl这些nginx源码编译必需的依赖提前收集成rpm集合,在目标机器上一条命令装齐,然后顺利configure、make、install,跑通一个能开机自启、能代理静态页面的nginx。
这套离线方案适合三类人:刚接手内网系统的运维、需要批量初始化多台服务器的实施工程师,以及被安全审计卡住、必须在物理隔离环境里完成web服务部署的开发。接下来的每一章都按实际落地顺序推进,中间会穿插我在不同发行版上反复踩过的坑,包括缺库、版本冲突、防火墙和SELinux的干扰。读完你应该能自己做出一个离线rpm仓库,并且对nginx的编译选项有足够清晰的把握。
2. 离线依赖盘点:nginx编译到底需要哪些rpm
2.1 依赖分层的逻辑:先编译链,再功能库
nginx源码安装需要编译器,这是第一层依赖。gcc负责把C代码编成目标文件,gcc-c++负责处理少量使用C++语法的模块,make则驱动整个构建过程。没有这三样,configure脚本根本跑不起来。第二层是功能库:nginx的URL重写模块依赖pcre,gzip模块依赖zlib,HTTPS服务依赖openssl。它们分别对应pcre-devel、zlib-devel和openssl-devel三个开发包。注意这里的devel后缀不能省,因为nginx编译时需要的是头文件,而不只是运行时库。
第二层依赖往往是初学者最容易翻车的地方。有人只装了pcre没装pcre-devel,configure阶段直接报“the HTTP rewrite module requires the PCRE library”。这不是缺库,是缺头文件。rpm包集合里必须同时包含运行库和开发库,缺哪个都不行。我一般会先在一台能联网的同版本系统上用yum把依赖拉下来,再搬到内网机器上装,这样版本和依赖关系都是系统自己解析好的,不会出现手动rpm -ivh时顺序混乱的问题。
2.2 基础rpm集合清单:最小化但够用
在CentOS 7或相似版本的系统上,我常用的基础rpm集合包括以下这些包:gcc、gcc-c++、make、pcre、pcre-devel、zlib、zlib-devel、openssl、openssl-devel,再加上kernel-headers和glibc-headers这类编译时会被间接依赖的基础包。实际操作中你不需要手敲这一长串包名,而是用yumdownloader带着依赖解析去拉,详见下一章。这里先把清单列出来,方便你在收集完成后逐一核对。
文件清单形式:
| 包名 | 用途 | 是否含devel |
|---|---|---|
| gcc | C语言编译 | 否 |
| gcc-c++ | C++语言编译 | 否 |
| make | 构建工具 | 否 |
| pcre / pcre-devel | 正则表达式与rewrite模块 | 是 |
| zlib / zlib-devel | gzip压缩模块 | 是 |
| openssl / openssl-devel | HTTPS与SSL模块 | 是 |
| glibc-headers / kernel-headers | 系统底层头文件 | 是 |
2.3 版本匹配的常用判断原则
离线安装最怕版本号对不上。nginx对pcre和openssl的版本并不挑到极端严格的程度,但要注意操作系统本身的openssl版本如果过旧,某些nginx模块可能在编译期能过,运行期遇到特定TLS版本才出问题。我的判断原则是:优先与目标系统自带的系统库版本保持一致,而不是追新。因为内网系统往往还跑着其他业务,贸然替换系统级别的openssl或zlib可能引发其他程序连锁异常。nginx可以通过静态编译的方式把部分库编进二进制里,但这会增加维护成本,不推荐默认这么做。
提示:如果你面对的是CentOS 6这类老系统,建议先确认系统自带gcc版本是否过旧。过旧时要么换新系统,要么准备更高版本的devtoolset,否则nginx某些新模块会干脆不支持。老系统上的离线部署,时常会败在编译器版本上,这不是玄学,是平铺直叙的客观限制。
3. 把依赖打成离线包:本地yum仓库的构建与核对
3.1 如何用yumdownloader一次性拉全依赖
在能联网的一台机器上,用yumdownloader命令是最省事的收集方式。这个工具来自yum-utils,如果没有就先用yum install -y yum-utils装好。它的核心能力是解析依赖关系,把指定包和它们依赖的包一起下载到本地目录。注意要加上--resolve参数,否则只下载指定的几个rpm,不会处理它们的依赖链。
# 创建保存rpm的目录 mkdir -p /opt/nginx-offline-rpms cd /opt/nginx-offline-rpms # 用yumdownloader拉取nginx编译所需依赖及全部依赖链 yumdownloader --resolve --destdir=/opt/nginx-offline-rpms \ gcc gcc-c++ make \ pcre pcre-devel zlib zlib-devel \ openssl openssl-devel参数说明:--resolve让yum自动解析每个包的所有依赖并一并下载;--destdir指定输出目录。执行后你会看到类似“examining xxx: gcc-4.8.5-44.el7.x86_64.rpm”的输出,这就是yum在逐个解析依赖链。下载完成后建议检查一下目录里的rpm数量,通常会在60到80个之间,因为gcc和openssl本身还会带出大量底层依赖。
3.2 创建本地yum仓库:createrepo的关键步骤
rpm包收集完成后,裸用rpm -ivh逐个安装会非常痛苦,几十个包存在相互依赖,必须按顺序安装。更理性的做法是建一个本地yum仓库,让yum自动解析依赖顺序。createrepo就是用来生成仓库元数据的工具。
# 安装createrepo工具 yum install -y createrepo # 在rpm目录下生成仓库元数据 createrepo /opt/nginx-offline-rpms # 验证仓库元数据是否生成成功 ls -l /opt/nginx-offline-rpms/repodata/createrepo执行完毕后会在目录下生成repodata文件夹,里面是仓库的索引文件。生成的仓库可以拷贝到U盘或直接拷贝到目标机器,放任意路径都行。然后在内网机器上写一个指向该目录的repo文件,yum install就能像联网环境一样自动解析依赖顺序了。这个技巧的价值在于:你不需要关心这几十个rpm谁先谁后,yum全包了。
3.3 内网机器的repo配置与安装验证
# 在目标机器上创建repo文件 vi /etc/yum.repos.d/nginx-local.repo # 内容如下 [nginx-local] name=nginx offline rpm repo baseurl=file:///opt/nginx-offline-rpms enabled=1 gpgcheck=0gpgcheck=0必须设置,因为离线收集的rpm包多半没有对应的官方签名信息。设置完成后,先执行yum clean all清空缓存,再试装一遍,看依赖解析是否顺畅。
# 清空yum缓存 yum clean all # 测试依赖解析与安装 yum install -y gcc gcc-c++ make pcre-devel zlib-devel openssl-devel如果这条命令没有任何报错,说明本地仓库构建成功,依赖链完整。这时再用rpm -qa逐一核对版本,确认与目标系统匹配。我一般在确认安装成功后,会把这个目录和repo文件复制一份留档,下次初始化新机器直接复用,能省不少时间。需要说明的是,不同系统的yum版本对repo配置的写法略有差异,比如部分新发行版要求repo文件中显式声明metalink或mirrorlist为空,否则会尝试访问外网导致超时。后续内网机器越来越多时,也可以把baseurl换成局域网内的http地址,让其他机器通过内网镜像直接安装,这比反复拷贝U盘要顺得多。
注意:用本地方案时不要只拷rpm目录而忘了repo文件,否则目标机器不会自动识别这个仓库。repo文件本身就是离线仓库能用的关键,很多新手在这里卡住,反复手装rpm然后被依赖坑到怀疑人生。
4. 执行安装:从configure到启动的完整参数链
4.1 configure参数的取舍原理
依赖装齐之后,真正编译nginx前要决定启用哪些模块。这里不是简单跑个默认configure就完事,而是要想清楚这台nginx将来要承担什么角色。如果核心是静态文件与反向代理,我建议至少带上http_ssl_module、http_stub_status_module和stream模块,其中stream模块负责TCP/UDP四层转发,nginx从1.9.0起加入,很多人在做负载均衡时才想起来缺了这个模块,只能回头重新编译,白白折腾一遍。
# 解压nginx源码包 tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 # 编译前配置,按需启用模块 ./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/usr/local/nginx/conf/nginx.conf \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-stream \ --with-threads参数说明:--prefix决定nginx安装根目录,后续所有路径都以它为基础;--with-http_ssl_module开启HTTPS支持,需要openssl-devel已经安装成功;--with-stream启用四层转发能力,做代理时常用;--with-threads用线程池处理多核环境下的并发请求,对静态文件服务有明显提升。configure脚本执行后,看到“Configuration summary”部分列出的module列表,基本就能确认哪些模块成功编译进去了。
4.2 make与make install的全过程
configure通过后,剩下的两步就是make和make install。这里我想强调的是,make过程的报错信息是判断依赖是否真正安装成功的最后一环。如果你在make阶段看到“pcre.h: No such file or directory”,那就是pcre-devel没装上;如果看到“openssl/ssl.h: No such file”,那就是openssl-devel缺失。这些报错的排查方式很直接:缺哪个头文件就补哪个devel包,补完重新configure再make。
# 编译nginx源码 make -j4 # 安装到指定目录 make install # 检查nginx二进制是否生成 ls -l /usr/local/nginx/sbin/nginx-j4表示用4个线程并行编译,机器核数少可以改成-j2或直接make。make install将编译好的文件安装到prefix指定的目录。执行完ls命令看到nginx可执行文件,说明编译链整体是通的。这时候别急着启动,先确认一下版本号和编译参数是否与预期一致。
4.3 启动与开机自启的完整配置
第一次启动nginx建议用-t先测试配置文件语法,这是最廉价的事故预防手段。配置测试通过后启动nginx,再用curl做本地验证。开机自启我习惯写一个systemd服务文件,因为内网服务器重启后nginx必须自动拉起,这是生产环境的刚需。
# 测试配置文件语法 /usr/local/nginx/sbin/nginx -t # 启动nginx /usr/local/nginx/sbin/nginx # 查看nginx进程状态 ps -ef | grep nginx # 本地请求验证服务是否响应 curl http://127.0.0.1/# 创建systemd服务文件 vi /etc/systemd/system/nginx.service # 内容如下 [Unit] Description=nginx - high performance web server After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target# 重新加载systemd配置并启用开机自启 systemctl daemon-reload systemctl enable nginx.service systemctl start nginx.service参数说明:Type=forking表示nginx主进程会fork出worker进程,systemd需要根据PIDFile跟踪主进程状态;ExecStop用nginx -s quit做优雅退出,比暴力kill更能保证请求不中断。启用成功后,用systemctl status nginx命令能看到active (running)状态,这样即使内网机器意外重启,nginx也会自己找回来。
5. 离线安装依赖与编译的常见问题排查:4条血泪经验
5.1 系统自带openssl被替换导致yum故障
现象:我在某台机器上为了装新版openssl,直接编译安装了到/usr/local/openssl,然后把系统openssl的软链接替换了。结果第二天执行yum报错无法解析https源,系统里一堆依赖openssl的软件也开始报错。
原因:系统yum和curl依赖的是系统自带的openssl库路径,手动替换成新版本后,库版本或ABI不兼容,导致原有程序加载失败。
解决:最终通过恢复系统自带openssl并重装受影响包才恢复。现在我的习惯是nginx编译时通过--with-openssl指向额外下载的源码目录,不碰系统openssl。这样nginx有了新版TLS特性,系统库保持原样,两边互不干扰。
5.2 configure报错CRITICAL: pcre not found
现象:configure阶段报“the HTTP rewrite module requires the PCRE library”,但rpm -qa已经看到pcre已安装。
原因:只装了pcre主包没装pcre-devel,头文件缺失。编译nginx需要的是开发头文件pcre.h,而运行时才需要libpcre.so,主包不带头文件。
解决:执行yum install -y pcre-devel,重新configure。这个案例提醒我收集rpm集合时,需要同时拉取主包和devel包,缺一不可,versus这个问题的现象虽然简单,但在离线环境下因为没有网络可以随手补包,常常会让整个部署停摆。
5.3 make阶段找不到zlib.h
现象:make执行到一半报zlib.h找不到,编译中断。
原因:zlib-devel没有安装,或者安装了但configure时使用了--with-zlib=指定路径,而该路径并不存在。有时候是路径写错了,有时候是根本没有下载zlib源码包。
解决:确认zlib-devel已安装后,重新执行configure再make。如果依然报错,检查configure参数里是否残留了旧的--with-zlib目录配置。这里要格外注意configure的缓存,修改参数后必须删掉auto目录下生成的缓存文件再重新configure,否则旧配置会持续干扰。
5.4 SELinux阻止nginx绑定80端口
现象:nginx -t正常,启动也提示success,但外部访问始终连不上,curl报connection refused。
原因:SELinux的httpd_can_network_connect策略没有开启,nginx作为非标准web进程尝试绑定端口或进行网络转发时被拦截。
解决:执行setsebool -P httpd_can_network_connect 1开放网络连接权限,如果nginx使用自定义端口比如8080,还需要用semanage port -a -t http_port_t -p tcp 8080把端口加入SELinux放行列表。这条问题在rpm安装的场景里反而不常遇到,因为rpm包装的nginx会自动打上正确的SELinux标签,而源码编译安装的二进制文件则会被SELinux当成未知程序处理,所以如果你用离线编译方案部署nginx,这一步务必提前确认。
6. 验证安装结果与扩展模块的思路
nginx安装完成后,用一条命令验证模块和版本信息是最快的自检手段。这条命令值得养成习惯:
# 查看nginx版本及编译参数 /usr/local/nginx/sbin/nginx -V-V输出里能看到configure arguments一长串内容,我每次都会读一遍,确认自己想要的模块都在里面。这时再用curl访问测试页面,正常情况下能看到“Welcome to nginx”。如果返回403,优先检查nginx运行用户对网页目录的权限,这比反复重启nginx要高效得多。
编译参数之外的扩展方向,我通常建议先从stub_status模块开始。它提供一个内置的页面,展示当前活跃连接数、请求总数等指标。在server配置里加一段location指向nginx_status即可:
location = /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }这样配置后,通过http://127.0.0.1/nginx_status就能看到Active connections、server accepts handled requests等实时数据。这是对编译模块功能的验证,也是最简单的Nginx监控手段,配合zabbix或prometheus的采集器,可以快速画出一张基础请求量趋势图。
我最后想分享的习惯是:每做完一次离线部署,把configure参数、安装用的rpm清单、repo配置文件都归档到一个固定目录,旁边写一个readme说明系统版本和安装日期。这样半年后要扩容新机器或升级nginx时,不需要重新回忆当时用了什么模块,直接翻归档文件就能照着复现一遍。内网环境里时间成本往往是最贵的,归档能省下大量翻工的量。希望帮到你,这套离线rpm方案在你手里能跑得比我这还顺。
本文还有配套的精品资源,点击获取