
简介面向离线或内网环境下的 Linux 服务器运维人员这套资源将 nginx 离线安装过程中所需的编译器依赖包与 nginx 自身依赖集合整合为一体解决无网络时无法用常见包管理器安装的痛点。压缩包共 4 个文件以三个 gz 格式的依赖归档为主要内容分别对应编译工具链和 nginx 运行依赖另附一个 html 安装说明文档整体大小约 62.15 兆字节方便直接拷贝至内网服务器使用。目前已有 1682 人学习使用。借助打包好的 rpm 依赖集合读者可快速搭建编译环境、完成 nginx 部署同时配套文档针对版本匹配和依赖冲突提供了详细的排查思路能显著降低安装失败概率。该资源尤其适合高并发静态服务、反向代理等场景也可与基于 Java 的中间件组合实现动静分离从而提升服务器整体吞吐与响应能力是内网环境高效部署 nginx 的实用工具。1. nginx离线安装到底在卡谁把一台内网服务器交付到现场装应用前先装 nginx结果发现系统里连 gcc 都没有。yum 源指向外网网络不通rpm 包手里一个也没有上网查资料只能靠手机。这时候你才明白nginx离线安装这件事难点从来不在 nginx 本身而在它前面那一长串依赖。标题里说的“包含 gcc、nginx 的依赖包 rpm 集合”就是把整条依赖链提前在联网机器上备好再搬到离线机器上一次性装齐。这篇笔记就是沿着这条路径走一遍从依赖怎么下载、怎么打包到本地 yum 源怎么建、nginx 怎么编再到最常见的翻车点适合内网交付、机房实施、以及所有被“没网装不了东西”卡住过的同事。2. 装 nginx 之前先把 gcc 依赖打包成 rpm 集合2.1 nginx 编译依赖 gcc 与三个基础库版本关系先搞清楚nginx 官方提供的二进制包在部分内网环境里未必适用最常见的方式还是源码编译。源码编译需要一套完整的 C 编译器也就是 gcc 和 gcc-c再加上 make。这三样是“编译工具链”没有它们configure 脚本第一步就会直接报错。除了编译器nginx 编译还依赖三个基础库pcre 负责正则表达式zlib 负责 gzip 压缩openssl 负责 HTTPS。对应到 rpm 包上不仅要装 pcre、zlib、openssl 本体还要装 pcre-devel、zlib-devel、openssl-devel因为编译时需要的头文件都在 devel 包里。很多新手只装了本体没装 develconfigure 跑一半提示找不到头文件就是这个原因。版本匹配上CentOS 7 默认自带 pcre 1.x 和 openssl 1.0.2k编 nginx 1.18 到 1.24 都没问题CentOS 8 系统自带的是 pcre2 和 openssl 1.1.1直接用系统库也能编过。需要特别注意的是别把 CentOS 8 的 rpm 包拿到 CentOS 7 机器上装gcc 版本、glibc 版本都可能对不上这是离线安装里最常见的版本串台问题。2.2 在联网机器上用 yumdownloader 一次性拉全 rpm 依赖下载依赖的机器要和离线机器系统版本一致最好大版本相同、小版本相近。比如目标机器是 CentOS 7.9就找一台 CentOS 7.x 的联网机器来下载不要用 CentOS 8 或别的发行版否则 rpm 包的兼容性很难保证。下载工具用 yumdownloader它在 yum-utils 包里需要先安装yum install -y yum-utils createrepo mkdir -p /opt/nginx-rpms cd /opt/nginx-rpms yumdownloader --resolve --destdir/opt/nginx-rpms \ gcc gcc-c make \ pcre pcre-devel zlib zlib-devel \ openssl openssl-devel \ createrepo--resolve参数会自动把指定包的依赖一起下载这是最关键的一个选项。不加它yumdownloader 只下载你列出的 rpm依赖不会跟着下来。createrepo也一起放进列表里因为离线机器上多半没有这个工具而后面建本地 yum 源必须用到它。下载时会遇到一个实际问题如果这台联网机器本身已经装过 gcc 或 opensslyumdownloader 会跳过已安装的包导致下载集合不完整。我一般会临时用一台最小化安装的干净机器来下载或者下载完统计一下 rpm 数量对照依赖关系检查。更保险的做法是用repotrack命令它会无视本机已安装状态把依赖全部拉下来repotrack gcc gcc-c make pcre-devel zlib-devel openssl-devel createreporepotrack会写到当前目录。它比 yumdownloader 多下载不少包包括已经装过的体积大一点但更稳妥。两种工具都在 yum-utils 里选一种即可。2.3 打包与传输rpm 集合要带上系统标识再上路下载完成后目录里通常是几十个 rpm 文件。打包时建议在压缩包名字里带上系统版本和架构方便以后复用和排查tar czf nginx-deps-centos7-x86_64.tar.gz /opt/nginx-rpms命名格式按“用途-系统-架构”来写比如nginx-deps-centos7-x86_64.tar.gz。别小看这一步离线环境越攒越多之后机器上会堆一堆 tar 包没有标识根本分不清哪个是给哪台机器用的。传输方式看现场条件U 盘拷、内网共享目录拉取都行。注意传输完成的校验用md5sum对比一下包校验值避免拷贝过程中文件损坏。文件拷到离线机器后解压mkdir -p /opt/nginx-rpms tar xzf nginx-deps-centos7-x86_64.tar.gz -C /opt解压后确认目录里 rpm 文件的数量和联网机器上一致。数量对不上就先别继续回查下载环节这一步省了后面全是坑。3. 离线机器上建本地 yum 源让 gcc 和 nginx 依赖一次装齐3.1 为什么不用 rpm -Uvh 直接批量装rpm 集合拿到手第一反应可能是rpm -Uvh *.rpm一把梭。这个命令在依赖简单时能成功但 gcc、openssl 这组依赖链比较复杂尤其是 openssl 可能和系统原有版本冲突或者某些包依赖的库版本顺序不对rpm -Uvh批量安装会因为一个依赖问题中断执行留下一堆半装状态。更麻烦的是回滚。rpm 批量安装失败后哪些包装上了、哪些没装上只能靠rpm -qa一个个查查完还得手动清理纯粹浪费时间。所以我一般不在离线机器上直接rpm -Uvh而是把 rpm 集合目录建成一个本地 yum 源。yum 会自己解析依赖关系自动决定安装顺序遇到缺包会明确报错提示而不是装到一半卡住。这个思路在 CentOS 6/7/8 上都适用。3.2 用 createrepo 生成本地仓库再把 gcc 全家装进去在解压好的 rpm 目录下执行 createrepo 生成仓库元数据cd /opt/nginx-rpms createrepo .执行成功后目录下会多出一个repodata子目录里面有仓库的元数据文件。这就是本地 yum 源的标识没有它 yum 无法识别这个目录。然后在/etc/yum.repos.d/下新建一个仓库配置文件[nginx-local] namenginx local deps repository baseurlfile:///opt/nginx-rpms enabled1 gpgcheck0baseurl用的是file://协议指向本地目录。gpgcheck0表示跳过 GPG 签名校验离线环境下这些包是自己下载的安全性可以自行把握。如果公司内网有签名校验要求可以保留gpgcheck1并导入对应公钥但一般离线场景没必要。配置完成后刷新缓存并安装yum clean all yum makecache yum install -y gcc gcc-c make pcre-devel zlib-devel openssl-devel这里有几个细节。第一yum clean all必须执行否则 yum 缓存里可能还是旧的仓库数据识别不到新增的本地源。第二安装的是 devel 包而非本体库因为本体库通常系统已经装了真正缺的是头文件。第三如果离线机器之前配置过外网 yum 源建议把外网源文件先移走或者禁用避免 yum 在解析依赖时去尝试访问不可达的地址导致超时等待。安装完成后用rpm -qa验证一下关键包是否到位。3.3 装完核对版本确认编译环境可用rpm -qa | grep -E ^(gcc|gcc-c|make|pcre|zlib|openssl)正常输出里能看到gcc-4.8.5、pcre-8.32、openssl-1.0.2k这一类的完整包名和版本号。核对两项内容一是 gcc 和 make 确实装上了二是 devel 包都在。只看本体的包名不算成功比如pcre装了但pcre-devel没装后面 configure 照样挂。这一步还可以顺手确认 openssl 的版本。CentOS 7 默认是 1.0.2k编 nginx 的 ssl 模块完全够用如果你准备配置 HTTP/2 或需要用 TLS 1.3就得确认系统 openssl 是不是 1.1.1 以上版本不是的话后面第 5 章有对应的处理说明。4. nginx 源码编译安装configure 参数与启动配置4.1 configure 最小参数集与路径约定依赖装齐之后把 nginx 源码包传到离线机器并解压。源码版本建议选当前主流稳定版比如 1.24 系列具体版本号按你下载的为准。进入解压目录后执行 configure我的最小参数集是cd /opt/nginx-1.24.0 ./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-stream--prefix指定安装路径后续所有文件会装到/usr/local/nginx下卸载时直接删这个目录就行。--with-http_ssl_module是必选项不加它 HTTPS 功能完全不可用。--with-http_stub_status_module提供/nginx_status页面日常看连接数很有用。--with-stream开启四层 TCP 代理能力做端口转发时用得上。不需要的模块不写参数越少编译时间越短.如果 configure 报错说找不到 pcre 或 zlib先检查第 3 章有没有把对应的 devel 包装上。常见报错是the HTTP rewrite module requires the PCRE library基本就是 pcre-devel 缺失回去yum install再重新 configure 即可。4.2 make 编译与常见的编译失败定位configure 通过之后再执行编译。离线机器内存普遍不大编译参数要克制make -j2 make install-j2表示用两个进程并行编译。如果机器内存小于 2G去掉-j直接make反而更快。内存不足时并行编译会因为内存耗尽被系统 kill 掉表现为进程消失、终端输出中断这种问题加-j1就能解决。make install会创建/usr/local/nginx目录并复制文件。编译失败时看终端输出里的error:行往上翻几个屏幕找到第一个 error那才是真正的原因。常见错误就是缺头文件、缺库回到 yum 安装对应 devel 包再重新./configure make。重新编译前不需要清理configure 会覆盖配置。4.3 启动 nginx 与配置开机自启安装完成后先做基础验证/usr/local/nginx/sbin/nginx -t /usr/local/nginx/sbin/nginx curl http://127.0.0.1nginx -t会检查配置文件语法输出syntax is ok和test is successful才算通过。启动后curl应该返回 nginx 默认欢迎页的 HTML 内容。手动启动只能让 nginx 临时运行重启机器后不会自动拉起。需要写一个 systemd service 文件放到/usr/lib/systemd/system/nginx.service[Unit] Descriptionnginx - high performance web server Afternetwork.target remote-fs.target nss-lookup.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 -c /usr/local/nginx/conf/nginx.conf ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s quit PrivateTmptrue [Install] WantedBymulti-user.target保存后执行systemctl daemon-reload systemctl enable nginx systemctl start nginx systemctl status nginxExecStartPre会在启动前自动做语法检查配置写错时服务启动会失败但能直接看到错误原因。这里用WantedBymulti-user.target系统进入多用户模式后自动启动 nginx。这一步做完nginx 离线安装就算基本落地了。5. nginx离线安装常见问题5个高频坑与排查路径5.1 现象rpmlib(FileDigests) 版本报错rpm 拒绝安装执行rpm -Uvh *.rpm时提示rpmlib(FileDigests) is needed by xxx有些包能装有些包直接拒绝。原因是离线机器的 rpm 版本太老识别不了新版 rpm 包的文件摘要格式。解决路径只有一个不要用rpm -Uvh直接装回到第 3 章的本地 yum 源方案yum 内部会处理这些差异。如果 yum 也报同样错误说明 rpm 包本身来自更新的系统版本换一批和目标系统版本匹配的 rpm 包。这个坑在 CentOS 6 和 CentOS 7 混用 rpm 时比较常见。下载依赖之前先用cat /etc/redhat-release确认目标系统版本再找对应版本的联网机器下载。5.2 现象openssl 版本过低ssl 模块编不过去configure 时指定--with-http_ssl_module报错提示 openssl 相关函数缺失或者提示OpenSSL version is too old。CentOS 7 默认 openssl 1.0.2k对大多数 nginx 场景够用但如果 nginx 新版本代码里用了 1.1.1 才有的 API就可能出现这个报错。解决方式分两种。一是换用旧的 nginx 版本和系统 openssl 匹配二是下载 openssl 1.1.1 源码单独编译再在 nginx configure 时用--with-openssl/path/to/openssl-source指定。第二种方式编译时间会明显变长并且之后升级 openssl 时 nginx 也要跟着重新编译维护成本高。除非业务明确需要 TLS 1.3否则我一般建议直接用系统自带 openssl少折腾。5.3 现象nginx 启动报 libpcre.so.1 找不到但 pcre 确实装了启动时提示error while loading shared libraries: libpcre.so.1用rpm -qa | grep pcre看到的却是pcre2-*的包。原因基本可以锁定为装的是 pcre2 而不是 pcre1。CentOS 8 系统默认带 pcre2但 nginx 1.24 及更早版本编译链接的是 pcre1 的库文件。系统找不到libpcre.so.1因为 pcre2 提供的是libpcre2-8.so.0。解决方式在本地 yum 源里补上pcre和pcre-devel两个包安装后再重新 configure、make、make install。注意下载依赖时把pcre显式写进 yumdownloader 列表别依赖系统自动带出来。这个问题的迷惑性在于看起来 pcre“已经装了”实际上装的是全然不同的另一个东西。5.4 现象make 报 cc1 无法识别的选项编译中断编译执行到一半报cc1: error: unrecognized command line option后面跟一串选项。原因是 gcc 版本和目标系统编译环境不匹配最常见的就是把 CentOS 8 的 gcc rpm 装到了 CentOS 7 机器上。rpm 安装时因为 glibc 版本碰巧满足装上了但编译参数不兼容。解决思路先gcc --version查看当前 gcc 版本确认是不是下载时搞混了系统来源重新用匹配的 rpm 集合安装。这个坑的根源在 2.3 节说的打包标识压缩包名字里写清楚系统版本就不会把集合搞混。5.5 现象SELinux 拦截 80 端口页面打不开nginx 启动正常curl http://127.0.0.1也能通但从其他机器访问 80 端口就是不通或者systemctl status nginx显示 active 但网页超时。优先怀疑 SELinux。getenforce如果输出Enforcing十有八九是 SELinux 不允许 nginx 监听 80 端口。SELinux 的策略里默认只放行了某些端口非标准端口或未登记的端口会被拦。临时验证可以先setenforce 0切到 Permissive再访问页面。如果通了说明就是 SELinux 的问题。然后找一台联网机器下载policycoreutils-python-utils这个包装了之后用 semanage 放行端口semanage port -a -t http_port_t -p tcp 80或者干脆给 nginx 写一条自定义 SELinux 策略这是正规做法但对离线环境来说成本偏高很多现场就是直接放行端口了事。顺带一提SELinux 拦截这类问题在 CentOS 7 上表现得很隐蔽排查网络问题时习惯性先getenforce看看能少走很多弯路。6. 把 rpm 集合变成可复用的内网工具包6.1 一次性验证安装成果的命令序列离线环境交付时验证项目总得留下记录。我习惯用下面这一组命令输出存成文本作为交付物之一/usr/local/nginx/sbin/nginx -V /usr/local/nginx/sbin/nginx -t curl -I http://127.0.0.1 ss -lntp | grep :80 rpm -qa | grep -E ^(gcc|pcre|zlib|openssl)nginx -V输出的编译参数能看出装了哪些模块curl -I确认 HTTP 响应头正常ss确认监听端口rpm -qa确认依赖版本。这组输出同时写到项目交付文档里后续排障也有据可查。6.2 后续补依赖与多机复用的两种思路rpm 集合不是一次性的。同一个内网里往往有几十台同系统版本的机器后续还会在机器上装其他软件又缺新的依赖包。复用方式有两个一是把/opt/nginx-rpms这个目录直接打包保留后续补充新 rpm 时放进目录重新执行createrepo .让仓库元数据更新二是把这个目录通过内网 HTTP 服务开放其他机器把baseurlfile:///opt/nginx-rpms换成baseurlhttp://内网IP/nginx-rpms就能直接从内网拉依赖。我自己的习惯是给每类软件建独立目录比如nginx-rpms、python-rpms压缩包统一按“用途-系统-架构”命名。这样再遇到新机器安装环境直接解压、建源、装包三条命令搞定不用重新上网找资源。第一次做离线安装时我也干过把 pcre2 当成 pcre 用了半天的事最后发现是系统库里同名不同族。这类问题写下来比记在脑子里靠谱。希望这篇笔记能帮你少走几趟弯路。本文还有配套的精品资源点击获取