简介:面向无外网或网络受限环境下的 Linux 服务器运维人员,这份资源提供了一套完整的 nginx 离线部署方案,重点解决编译环境缺失与依赖包难以获取的问题。压缩包共 4 个文件,以 gz 源码与依赖归档为主,辅以一份 html 安装说明,整体约 62.15MB,便于一次性拷贝到目标机器后按说明逐步落地。内容围绕 gcc 编译套件与 nginx 依赖 rpm 集合展开,覆盖从编译环境准备到 nginx 安装所需的主要依赖,适合需要在内网数据中心、隔离机房中快速搭建 Web 与反向代理服务的初中级运维人员参考。已有 1683 人学习下载,说明该离线组合在实际运维场景中具有一定通用性。读者可据此减少逐台联网找包的时间,理清依赖安装顺序,并借助说明文档完成配置与启动,提升受限网络下的部署效率。
1. 内网机器装 nginx:为什么我每次都先翻依赖包清单
上周又碰到一台不能连外网的机器,要装 nginx 做静态资源服务。系统是最小化安装的 CentOS 7,gcc没有,pcre-devel、zlib-devel、openssl-devel一个都没有,直接./configure就是一路报错。这种场景在运维里太常见了:生产环境隔离、机房只开内网、客户现场不给外网权限,nginx 又偏偏是绕不开的那一层。装不好会怎样?最典型的就是编译到一半卡在checking for C compiler ... not found,或者编译过了启动时报error while loading shared libraries,服务起不来还查不出原因。这篇笔记就是给卡在这一步的开发者看的,从 gcc 到 nginx 依赖 rpm 集合,一步步把离线环境搭起来,新手能照着走通,熟手能看到版本取舍和踩坑点。
2. 装前把环境盘清楚:系统版本、gcc 与依赖 rpm 的对应关系
离线安装 nginx 最容易翻车的地方不是 nginx 本身,而是依赖链没盘清。nginx 源码编译依赖四类东西:C 编译器(gcc 及其依赖)、PCRE(正则,用于location匹配)、zlib(gzip 压缩)、OpenSSL(HTTPS 支持)。这四类在联网机器上一条yum install就解决了,离线环境必须提前把 rpm 包凑齐,而且要和目标机器的系统版本、架构严格对应。
2.1 先确认目标机器的系统与架构
动手之前先在目标机器上跑三条命令,把底数摸清。系统大版本决定 rpm 包从哪个源取,架构决定包名后缀,glibc 版本决定 gcc 能不能装。
# 查看系统版本,确认是 CentOS 7 还是 8、Rocky 还是 Alma cat /etc/os-release # 查看架构,x86_64 还是 aarch64,包名后缀完全不同 uname -m # 查看 glibc 版本,gcc 的 rpm 对 glibc 有最低要求 ldd --version | head -n 1/etc/os-release里的VERSION_ID是关键,CentOS 7 是7,CentOS 8 / Rocky 8 是8,两代系统的 rpm 包不能混用。uname -m输出x86_64就取x86_64.rpm,输出aarch64就得找aarch64的包,拿错了装上去会报package is intended for a different architecture。ldd --version看 glibc,CentOS 7 一般是 2.17,CentOS 8 是 2.28,gcc 的 rpm 如果要求更高版本的 glibc,装的时候会直接冲突。
我一般会在联网的同版本机器上先做一次对照,把目标机器和联网机器的os-release、uname -m输出并排比一下,确认完全一致再开始凑包。这一步多花两分钟,能省掉后面半小时的依赖报错。
2.2 gcc 及编译工具链的 rpm 清单
最小化安装的系统连make都没有,gcc 也不是单个包,而是一串。下面这张表是我在 CentOS 7 x86_64 上实际凑过的一套,缺一个都可能编译中断。
| 包名 | 作用 | 是否必需 |
|---|---|---|
| gcc | C 编译器主包 | 必需 |
| gcc-c++ | C++ 编译器,部分依赖会用到 | 建议装 |
| glibc-devel | C 库头文件 | 必需 |
| glibc-headers | C 库头文件 | 必需 |
| kernel-headers | 内核头文件 | 必需 |
| libmpc | gcc 依赖的数学库 | 必需 |
| mpfr | gcc 依赖的浮点库 | 必需 |
| cpp | 预处理器 | 必需 |
| make | 构建工具 | 必需 |
| autoconf / automake | 部分源码包需要 | 按需 |
这些包之间有依赖顺序,直接rpm -ivh *.rpm一把梭经常报Failed dependencies。常见做法是先rpm -ivh装底层库(glibc、libmpc、mpfr),再装 gcc 主包,最后装 make。如果嫌手动排序麻烦,可以用yum localinstall *.rpm,让 yum 自己算依赖顺序,前提是本地源配好了。
2.3 nginx 三大依赖:pcre、zlib、openssl 的版本取舍
nginx 源码编译时./configure会去探测这三个库,探测不到就报错。离线环境有两种做法:装 devel 的 rpm 包,或者把源码包一起带过去手动编译。前者省事,后者灵活,我一般优先用 rpm。
- pcre:nginx 的
rewrite、location ~正则全靠它。CentOS 7 自带的是 pcre 8.x,装pcre和pcre-devel两个包。注意 nginx 1.22 之后对 pcre2 的支持更完整,如果目标系统是 CentOS 8 及以上,优先用pcre2和pcre2-devel。 - zlib:gzip 压缩模块依赖,装
zlib和zlib-devel。这个包一般系统自带,但最小化安装可能没有 devel。 - openssl:要开 HTTPS 就必须有
openssl和openssl-devel。这里有个版本坑:nginx 对 openssl 1.1.1 和 3.x 的支持在不同版本间有差异,CentOS 7 自带 1.0.2,够用但偏老;如果要上 TLS 1.3,得自己带 openssl 1.1.1 以上源码编译,配置时用--with-openssl=指定路径。
提示:pcre、zlib、openssl 的 devel 包版本要和运行库版本一致,混装不同小版本容易出现头文件和库文件对不上的情况,编译能过但运行时报符号找不到。
3. 离线包怎么凑、怎么传、怎么装:从联网机到目标机的完整链路
环境盘清之后,核心工作就是「凑包」和「传包」。这一步的难点不在技术,在细心:包要凑全、版本要对、传输过程不能损坏。我见过太多次因为少一个kernel-headers或者传包时断点续传出错,导致编译到一半失败,回头重来。
3.1 在联网机器上用 yumdownloader 凑齐 rpm
最稳的凑包方式是在一台和目标机器同版本、同架构的联网机器上,用yumdownloader把包和依赖一起下载下来。yumdownloader属于yum-utils,先装上。
# 安装 yum-utils,拿到 yumdownloader 和 repotrack yum install -y yum-utils # 建一个目录专门放包 mkdir -p /tmp/nginx-offline/packages cd /tmp/nginx-offline/packages # 下载 gcc 及其全部依赖,--resolve 会把依赖树一起拉下来 yumdownloader --resolve --destdir=/tmp/nginx-offline/packages gcc gcc-c++ make # 下载 nginx 三大依赖的 devel 包 yumdownloader --resolve --destdir=/tmp/nginx-offline/packages \ pcre pcre-devel zlib zlib-devel openssl openssl-devel--resolve是关键参数,它会把指定包的依赖递归下载,避免只下主包漏掉依赖。--destdir指定输出目录,所有 rpm 会平铺在这个目录里。如果依赖树很深,yumdownloader偶尔会漏,这时候用repotrack更彻底:
# repotrack 会把完整依赖树全部下载,适合依赖复杂的场景 repotrack -p /tmp/nginx-offline/packages gcc gcc-c++ make pcre-devel zlib-devel openssl-develrepotrack的-p指定下载目录,它比yumdownloader --resolve更激进,会把所有相关包都拉下来,包数量多但不会漏。我一般先用yumdownloader,装的时候报缺再补repotrack。
nginx 源码包本身也要带上,从官方下载对应版本的 tar.gz,和 rpm 放一起。版本选择上,稳定版优先,比如 1.24.x 或 1.26.x,不要追 mainline 的最新版,离线环境出问题不好回退。
3.2 打包传输与完整性校验
包凑齐后打成 tar 包传过去。传输方式看环境,U 盘、内网 scp、跳板机中转都行,关键是传完要校验。
# 在联网机打包,同时生成 md5 清单 cd /tmp/nginx-offline tar -czvf nginx-offline.tar.gz packages/ nginx-1.24.0.tar.gz md5sum nginx-offline.tar.gz > nginx-offline.tar.gz.md5 # 传到目标机后先校验,再解压 md5sum -c nginx-offline.tar.gz.md5 tar -xzvf nginx-offline.tar.gz -C /opt/md5sum -c会比对清单里的哈希,输出OK才说明传输没损坏。这一步别省,我踩过一次 U 盘拷贝大文件尾部截断的坑,解压出来的 rpm 装到一半报cpio: premature end of archive,查了半天才发现是传输问题。解压到/opt/下,后面统一从这个目录装。
3.3 按依赖顺序安装 rpm 并验证 gcc 可用
装包顺序有讲究,先底层库后上层工具。手动装的话按这个顺序:
cd /opt/packages # 第一层:基础库,glibc 相关和 gcc 的数学库依赖 rpm -ivh glibc-devel-*.rpm glibc-headers-*.rpm kernel-headers-*.rpm \ libmpc-*.rpm mpfr-*.rpm cpp-*.rpm # 第二层:gcc 主包和 make rpm -ivh 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如果顺序拿不准,用yum localinstall让 yum 算:
# 本地目录当源,yum 自动解决依赖顺序 yum localinstall -y /opt/packages/*.rpm装完立刻验证 gcc 和 make 是否可用,别等到编译 nginx 时才发现工具链有问题:
gcc --version make --version # 编译一个最小 C 程序,确认头文件和链接都正常 echo 'int main(){return 0;}' > /tmp/t.c && gcc /tmp/t.c -o /tmp/t && /tmp/t && echo "toolchain ok"gcc --version能输出版本号说明主包装上了,但头文件缺失时编译仍会失败,所以补一个最小 C 程序编译测试。输出toolchain ok才算工具链真正可用。
4. 编译安装 nginx:configure 参数怎么选、make 报错怎么读
工具链就位后,进入 nginx 本身的编译。这一步的坑集中在./configure的参数选择和make阶段的报错解读上。参数选错会导致模块缺失,报错读不懂会让人误以为是依赖没装好,其实是参数问题。
4.1 configure 参数逐项说明与推荐组合
nginx 的./configure参数很多,离线环境常用的就那几个。先解压源码,进目录,然后按需组合。
cd /opt tar -xzvf nginx-1.24.0.tar.gz cd nginx-1.24.0 # 推荐组合:指定安装路径、开 HTTPS、开状态页、开 gzip 相关 ./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-zlib=/usr \ --with-openssl=/usr逐项说:--prefix决定安装目录,我习惯放/usr/local/nginx,和系统包管理的路径分开,卸载时直接删目录。--with-http_ssl_module开 HTTPS,依赖 openssl-devel,不开的话后面配 443 会报unknown directive "ssl"。--with-http_stub_status_module开状态页,监控用得上。--with-http_gzip_static_module支持预压缩的.gz静态文件。--with-pcre、--with-zlib、--with-openssl是指定依赖路径,系统装了 devel 包的话一般能自动探测到,显式写上更稳。
如果 openssl 是自己源码编译的高版本,--with-openssl=要指向源码目录而不是安装目录,这是 nginx 的约定,指向错了会报找不到openssl/ssl.h。
./configure跑完会输出一个汇总,重点看两处:Configuration summary里列出的模块是否符合预期,以及最后有没有error。有 error 就往上翻,通常是某个 devel 包没装或路径不对。
4.2 make 与 make install 阶段的典型报错解读
./configure通过后,make阶段仍可能报错,这时候的报错信息比 configure 阶段更具体,但也更容易误读。
# 编译,-j 按 CPU 核数并行,加快速度 make -j$(nproc) # 编译成功后安装 make installmake -j$(nproc)用全部核并行编译,nproc输出核数。并行编译偶尔会因为依赖顺序问题报错,如果报错信息看起来莫名其妙,先去掉-j单线程重跑一次,能过就说明是并行竞争问题,不是代码问题。
典型报错一:fatal error: pcre.h: No such file or directory。这是 pcre-devel 没装或路径没指定,检查rpm -qa | grep pcre,确认 devel 包在,再确认--with-pcre路径。
典型报错二:undefined reference to 'SSL_CTX_new'。这是链接阶段找不到 openssl 库,通常是 openssl-devel 版本和运行库不匹配,或者--with-openssl指向了错误的目录。用rpm -qa | grep openssl核对版本一致性。
典型报错三:make: *** No rule to make target 'build'。这多半是./configure没跑成功,或者跑在了错误的目录。确认当前目录下有Makefile,没有就重新./configure。
make install一般不会报错,装完在--prefix指定的目录下能看到sbin/nginx、conf/nginx.conf、logs/等。
4.3 安装后的目录结构与关键文件
装完先认目录,后面配置和排错都靠它。
| 路径 | 内容 | 说明 |
|---|---|---|
| /usr/local/nginx/sbin/nginx | 主程序 | 启动、停止、重载都靠它 |
| /usr/local/nginx/conf/nginx.conf | 主配置 | 全局配置和 server 块 |
| /usr/local/nginx/logs/ | 日志目录 | access.log、error.log、nginx.pid |
| /usr/local/nginx/html/ | 默认站点 | 静态文件根目录 |
logs/nginx.pid存主进程 PID,nginx -s reload靠它找进程。error.log是排错第一现场,启动失败先看它。conf/nginx.conf里默认监听 80,离线环境如果 80 被占用,改listen端口再启动。
5. 避坑与排查:离线装 nginx 最常见的五个翻车点
离线环境的坑和联网环境不一样,联网时yum帮你兜底,离线时每个依赖都得自己扛。下面五条是我实际踩过、也帮别人排查过的,按「现象 → 原因 → 解决」记下来。
5.1 现象:rpm 装 gcc 报 Failed dependencies
原因:gcc 依赖 glibc-devel、libmpc、mpfr 等,手动rpm -ivh不解决依赖顺序,先装 gcc 主包就会报缺依赖。
解决:改用yum localinstall /opt/packages/*.rpm让 yum 算顺序,或者按 3.3 节的顺序先装底层库。如果 yum 也报缺,说明包没凑全,回联网机用repotrack补下。
5.2 现象:configure 报 C compiler cannot create executables
原因:gcc 装上了但头文件或链接器有问题,常见于只装了 gcc 主包、漏了 glibc-devel 和 kernel-headers。
解决:跑 3.3 节的最小 C 程序编译测试,确认工具链完整。报这个错时看config.log,里面会写明是哪个头文件或库找不到,按提示补包。
5.3 现象:启动 nginx 报 error while loading shared libraries
原因:编译时链接的库在目标机器上不存在或版本不对,典型是 openssl 或 pcre 的运行库版本和 devel 包不一致。
解决:ldd /usr/local/nginx/sbin/nginx看哪个库not found,用rpm -qa | grep核对运行库版本,补装对应版本的运行库 rpm。离线环境最容易出现 devel 包装了、运行库没装的情况。
5.4 现象:make 并行编译随机报错,单线程能过
原因:make -j并行时部分目标依赖顺序不确定,源码包的 Makefile 没处理好并行依赖。
解决:去掉-j单线程重跑,或者make -j2降低并行度。这不是环境问题,是构建脚本的并行安全性问题,单线程能过就以单线程为准。
5.5 现象:nginx 起来了但访问 403 或 404
原因:nginx.conf里root指向的目录不存在,或者index文件缺失,或者 SELinux 拦截了目录访问。
解决:先看error.log,403 常见是权限或 SELinux,getenforce确认状态,临时setenforce 0验证是不是 SELinux 问题;404 检查root路径和index配置。离线环境经常忘了建站点目录,root指向一个不存在的路径。
6. 装完怎么验证:三条命令确认 nginx 真的跑通了
装完不验证等于没装。我见过太多「装完了」结果服务起不来、端口没监听、配置语法错的情况。验证分三层:配置语法、进程与端口、实际请求。三层都过,才算这套离线环境真正跑通。
6.1 配置语法与进程状态检查
先做静态检查,再做动态检查。静态检查不启动服务,能提前发现配置错误。
# 检查配置语法,-t 只测试不启动 /usr/local/nginx/sbin/nginx -t # 启动 nginx /usr/local/nginx/sbin/nginx # 确认进程在,主进程和工作进程都要有 ps -ef | grep nginx | grep -v grep # 确认端口监听,默认 80 ss -lntp | grep nginxnginx -t输出syntax is ok和test is successful两行才算配置没问题。启动后ps应该能看到一个 master 进程和至少一个 worker 进程,只有 master 没有 worker 说明 worker 启动失败,去看error.log。ss -lntp确认 80 端口处于LISTEN状态,没有的话要么没启动成功,要么端口被占用改了配置没生效。
6.2 用 curl 做端到端请求验证
进程和端口都正常,最后用curl发一个真实请求,确认能返回内容。
# 请求本机,看返回状态码和内容 curl -I http://127.0.0.1/ # 如果改了端口,带上端口 curl -I http://127.0.0.1:8080/ # 看返回体前几行,确认是默认页或自己的站点 curl http://127.0.0.1/ | head -n 5curl -I只看响应头,返回HTTP/1.1 200 OK说明请求链路通了。返回 403 查目录权限和 SELinux,返回 404 查root和index,返回 502 说明反代后端有问题(离线静态站点一般不会)。curl拿不到响应但进程在,检查防火墙,firewall-cmd --list-ports看端口有没有放行。
6.3 重载与开机自启的收尾验证
服务跑通后,还要验证重载和自启,否则改配置或重启机器就露馅。
# 改配置后重载,不中断服务 /usr/local/nginx/sbin/nginx -s reload # 确认重载后进程还在、端口还在 ps -ef | grep nginx | grep -v grep ss -lntp | grep nginxreload是平滑重载,master 进程不变,worker 进程替换。重载后如果进程没了,说明新配置有语法错误导致启动失败,error.log里会有记录。开机自启离线环境一般写 systemd unit 或者塞进/etc/rc.local,写完systemctl enable后重启一次机器验证,别只 enable 不重启,重启后起不来才发现 unit 文件路径写错。
我现在的习惯是:每装完一台离线机器,nginx -t、ps、ss、curl四条命令强制走一遍,少一条都不算完。有一次赶时间只跑了nginx -t就交付,结果目标机器 SELinux 是 enforcing,curl直接 403,回头又跑一趟。从那以后这套验证流程我一次都没省过。希望帮到你。
本文还有配套的精品资源,点击获取