CentOS系统Nginx 1.19.6一键安装脚本详解与自动化运维实践

📅 2026/8/14 10:46:04
CentOS系统Nginx 1.19.6一键安装脚本详解与自动化运维实践
1. 为什么需要“一键安装”脚本从手动到自动的运维进化在服务器运维的日常里安装Nginx这类基础服务对很多老手来说可能只是几条命令的事。yum install nginx或者从源码./configure make make install看起来并不复杂。但如果你需要频繁地在不同环境的CentOS服务器上部署特定版本比如标题中的nginx-1.19.6事情就开始变得繁琐起来。你需要处理依赖包、下载指定版本的源码包、编译配置、处理可能出现的错误最后还要配置服务和开机自启。这个过程重复几次不仅耗时还容易因为环境差异比如缺少某个开发库而出错。这就是“一键安装”脚本存在的核心价值将重复、易错的手动操作封装成一个可靠、可复用的自动化过程。它不仅仅是为了“偷懒”更是为了标准化部署流程确保在任何目标机器上只要执行同一个脚本就能得到完全一致的服务环境。这对于需要批量部署、快速搭建测试环境、或者作为复杂应用部署前置条件的场景至关重要。今天我们就来深度拆解一个为CentOS系统定制的一键安装Nginx 1.19.6的脚本我会把每一行代码背后的意图、可能遇到的坑以及最佳实践都掰开揉碎了讲清楚。2. 脚本蓝图从需求到实现的完整设计思路在动手写脚本之前我们必须先想清楚这个脚本要完成哪些具体任务以及如何优雅地处理各种情况。一个健壮的安装脚本绝不仅仅是命令的堆砌。2.1 核心功能模块拆解针对“在CentOS上安装Nginx 1.19.6”这个目标我们的脚本需要按顺序完成以下关键步骤环境预检与依赖安装确认操作系统是CentOS并安装编译Nginx所必需的开发工具和库如gcc、pcre、openssl、zlib等。用户与组创建为Nginx服务创建一个专用的系统用户通常叫nginx以非root权限运行这是重要的安全实践。源码下载与校验从Nginx官方或可信镜像站下载指定版本1.19.6的源码包。为了安全最好能校验文件的MD5或SHA256哈希值。源码编译与安装解压源码包执行./configure设置安装路径、启用需要的模块如SSL、HTTP/2然后进行编译(make)和安装(make install)。服务化与开机自启创建Systemd服务单元文件nginx.service让Nginx可以通过systemctl命令管理启动、停止、重启、状态查看并设置开机自动启动。目录权限与防火墙配置调整Nginx日志、缓存等目录的权限并可选地配置Firewalld防火墙开放80HTTP和443HTTPS端口。安装后验证脚本最后应自动启动Nginx并通过访问本地页面或检查进程的方式验证安装是否成功。2.2 健壮性设计考量一个随处可用的脚本必须考虑异常情况幂等性脚本执行一次和多次的结果应该是一致的。如果Nginx已经安装是跳过还是卸载重装我们的设计通常是“如果已安装则跳过”。错误处理任何一步失败如下载失败、编译错误脚本都应该明确报错并退出而不是继续执行导致更混乱的状态。使用set -e命令可以让脚本在遇到错误时立即退出。日志记录将脚本的关键操作和输出记录到日志文件便于事后排查问题。参数化虽然叫“一键”但有时我们也希望有些灵活性比如指定安装目录、选择是否开启某些模块。可以通过读取脚本变量或命令行参数来实现。下面我们就将上述设计思路转化为具体的Shell脚本代码。3. 脚本逐行精讲不只是命令更是经验这里我将给出一个完整的、带有详细注释的脚本。你可以将这段代码保存为一个文件例如install_nginx_1.19.6.sh。#!/bin/bash # # CentOS 一键安装 Nginx 1.19.6 脚本 # 作者你的名字 # 版本v1.0 # # 启用严格模式任何命令失败返回非零状态则脚本立即退出 set -e # 定义颜色输出让提示信息更友好 RED\033[0;31m GREEN\033[0;32m YELLOW\033[1;33m NC\033[0m # No Color # 定义关键变量方便后续修改 NGINX_VERSION1.19.6 NGINX_SOURCE_URLhttp://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz # 建议将源码包哈希校验也加上这里以MD5为例实际生产环境推荐SHA256 # NGINX_SOURCE_MD5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx INSTALL_DIR/usr/local/nginx NGINX_USERnginx NGINX_GROUPnginx # 简单的日志函数 log_info() { echo -e ${GREEN}[INFO]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 } log_error() { echo -e ${RED}[ERROR]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 2 exit 1 } log_warning() { echo -e ${YELLOW}[WARNING]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 } # 检查当前用户是否为root check_root() { if [[ $EUID -ne 0 ]]; then log_error 此脚本必须以 root 用户权限运行。请使用 sudo 或切换至 root 用户。 fi log_info 权限检查通过。 } # 检查操作系统是否为CentOS check_os() { if [ -f /etc/redhat-release ]; then local os_version$(grep -oE [0-9]\.[0-9] /etc/redhat-release | head -1) log_info 检测到 CentOS ${os_version}。 # 可以在这里添加对特定版本的支持检查例如要求CentOS 7 else log_error 此脚本仅适用于 CentOS 系统。 fi } # 安装编译依赖 install_dependencies() { log_info 开始安装编译依赖包... # 使用 yum 安装开发工具组和必要的库 # -y 参数表示自动回答 yes在脚本中很常用 if yum groupinstall -y Development Tools; then log_info 开发工具组安装成功。 else log_error 安装开发工具组失败请检查yum源配置。 fi # 安装Nginx编译所需的特定库 local pkg_listpcre-devel openssl-devel zlib-devel wget if yum install -y $pkg_list; then log_info 依赖库 (${pkg_list}) 安装成功。 else log_error 安装依赖库失败。 fi } # 创建Nginx运行用户和组 create_nginx_user() { log_info 检查并创建Nginx运行用户和组... # 使用 id 命令检查用户是否存在如果不存在则创建 if ! id -u ${NGINX_USER} /dev/null 21; then useradd -r -s /sbin/nologin ${NGINX_USER} log_info 用户 ${NGINX_USER} 创建成功。 else log_warning 用户 ${NGINX_USER} 已存在跳过创建。 fi # 通常 useradd -r 会创建同名的组这里再确保一下组存在 if ! getent group ${NGINX_GROUP} /dev/null 21; then groupadd -r ${NGINX_GROUP} log_info 组 ${NGINX_GROUP} 创建成功。 fi } # 下载并解压Nginx源码 download_and_extract() { local source_filenginx-${NGINX_VERSION}.tar.gz local source_dirnginx-${NGINX_VERSION} log_info 开始下载 Nginx ${NGINX_VERSION} 源码包... # 使用 wget 下载-O 指定输出文件名 if wget -O ${source_file} ${NGINX_SOURCE_URL}; then log_info 源码包下载成功。 # 这里可以添加哈希校验逻辑 # if ! echo ${NGINX_SOURCE_MD5} ${source_file} | md5sum -c -; then # log_error 源码包MD5校验失败文件可能被篡改或下载不完整。 # fi else log_error 源码包下载失败请检查网络或URL。 fi log_info 解压源码包... if tar -zxvf ${source_file}; then log_info 源码包解压成功进入目录 ${source_dir}。 cd ${source_dir} else log_error 源码包解压失败。 fi } # 编译与安装Nginx compile_and_install() { log_info 开始配置编译参数... # 关键的configure步骤这里启用了常用模块 # --prefix 指定安装目录 # --user/--group 指定运行用户/组 # --with-http_ssl_module 启用SSL支持HTTPS必需 # --with-http_v2_module 启用HTTP/2支持 # --with-http_stub_status_module 启用状态监控模块 # --with-stream 启用TCP/UDP代理模块四层代理 ./configure \ --prefix${INSTALL_DIR} \ --user${NGINX_USER} \ --group${NGINX_GROUP} \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-stream \ --with-threads # 检查configure是否成功 if [ $? -eq 0 ]; then log_info 配置成功。 else log_error 配置失败请检查错误信息通常是缺少依赖库。 fi log_info 开始编译此过程可能需要几分钟取决于服务器性能... make if [ $? -eq 0 ]; then log_info 编译成功。 else log_error 编译失败。 fi log_info 开始安装到 ${INSTALL_DIR} ... make install if [ $? -eq 0 ]; then log_info Nginx 安装成功。 else log_error 安装失败。 fi # 返回上级目录保持脚本执行路径整洁 cd .. } # 创建Systemd服务文件 create_systemd_service() { local service_file/usr/lib/systemd/system/nginx.service log_info 创建Systemd服务文件: ${service_file} # 如果服务文件已存在先备份 if [ -f ${service_file} ]; then mv ${service_file} ${service_file}.bak.$(date %Y%m%d%H%M%S) log_warning 原服务文件已备份。 fi # 使用 cat 和 EOF 创建服务文件 cat ${service_file} EOF [Unit] DescriptionThe nginx HTTP and reverse proxy server Afternetwork.target remote-fs.target nss-lookup.target [Service] Typeforking PIDFile${INSTALL_DIR}/logs/nginx.pid ExecStartPre${INSTALL_DIR}/sbin/nginx -t ExecStart${INSTALL_DIR}/sbin/nginx ExecReload${INSTALL_DIR}/sbin/nginx -s reload ExecStop${INSTALL_DIR}/sbin/nginx -s quit PrivateTmptrue User${NGINX_USER} Group${NGINX_GROUP} [Install] WantedBymulti-user.target EOF if [ $? -eq 0 ]; then log_info Systemd服务文件创建成功。 # 重新加载systemd配置使新服务文件生效 systemctl daemon-reload log_info Systemd配置已重载。 else log_error 创建Systemd服务文件失败。 fi } # 配置目录权限与防火墙 post_installation() { log_info 设置Nginx目录权限... # 将安装目录的所有者改为root但赋予nginx用户访问权限 chown -R root:root ${INSTALL_DIR} # 将关键的客户端存储目录如fastcgi_temp, proxy_temp权限给nginx用户 if [ -d ${INSTALL_DIR}/client_body_temp ]; then chown -R ${NGINX_USER}:${NGINX_GROUP} ${INSTALL_DIR}/client_body_temp fi if [ -d ${INSTALL_DIR}/proxy_temp ]; then chown -R ${NGINX_USER}:${NGINX_GROUP} ${INSTALL_DIR}/proxy_temp fi if [ -d ${INSTALL_DIR}/fastcgi_temp ]; then chown -R ${NGINX_USER}:${NGINX_GROUP} ${INSTALL_DIR}/fastcgi_temp fi if [ -d ${INSTALL_DIR}/uwsgi_temp ]; then chown -R ${NGINX_USER}:${NGINX_GROUP} ${INSTALL_DIR}/uwsgi_temp fi if [ -d ${INSTALL_DIR}/scgi_temp ]; then chown -R ${NGINX_USER}:${NGINX_GROUP} ${INSTALL_DIR}/scgi_temp fi log_info 可选配置防火墙... # 检查firewalld是否运行 if systemctl is-active --quiet firewalld; then log_info 检测到firewalld正在运行尝试开放80和443端口。 firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --reload log_info 防火墙规则已添加。 else log_warning firewalld未运行请根据您的防火墙配置手动开放端口。 fi } # 验证安装 verify_installation() { log_info 启动Nginx服务并设置开机自启... systemctl start nginx systemctl enable nginx # 检查服务状态 local nginx_status$(systemctl is-active nginx) if [ ${nginx_status} active ]; then log_info Nginx服务启动成功 else log_error Nginx服务启动失败请使用 systemctl status nginx 和 journalctl -xe 查看详细错误。 fi # 尝试通过curl访问本地服务 log_info 尝试访问本地Nginx默认页面... if curl -s -o /dev/null -w %{http_code} http://localhost | grep -q 200; then log_info 验证成功Nginx正在运行并响应请求。 echo -e ${GREEN}${NC} echo -e ${GREEN} Nginx ${NGINX_VERSION} 安装完成${NC} echo -e ${GREEN} 安装目录: ${INSTALL_DIR}${NC} echo -e ${GREEN} 服务管理: systemctl {start|stop|restart|status} nginx${NC} echo -e ${GREEN} 配置文件: ${INSTALL_DIR}/conf/nginx.conf${NC} echo -e ${GREEN}${NC} else log_warning 无法通过HTTP访问本地服务但进程已启动。请检查防火墙或SELinux设置。 log_info Nginx进程信息 ps aux | grep nginx | grep -v grep fi } # 主执行流程 main() { log_info 开始 Nginx ${NGINX_VERSION} 一键安装 check_root check_os install_dependencies create_nginx_user download_and_extract compile_and_install create_systemd_service post_installation verify_installation log_info 安装脚本执行完毕 } # 执行主函数 main4. 脚本使用指南与深度避坑解析有了脚本我们还需要知道如何正确使用它以及如何应对执行过程中可能出现的各种问题。4.1 如何使用这个脚本保存脚本将上面的代码完整复制保存到你的CentOS服务器上例如/tmp/install_nginx.sh。赋予执行权限这是关键一步没有权限脚本无法运行。chmod x /tmp/install_nginx.sh以root权限执行sudo /tmp/install_nginx.sh或者直接切换到root用户后执行su - /tmp/install_nginx.sh观察输出脚本会输出彩色信息[INFO]为绿色[WARNING]为黄色[ERROR]为红色并会停止。请耐心等待编译完成。4.2 常见问题与排错手册即使脚本再完善在不同的服务器环境下也可能遇到问题。下面是我在实际部署中总结的几个高频坑点及其解决方案。问题一yum install失败提示Cannot find a valid baseurl或Could not resolve host原因服务器网络配置问题无法连接YUM仓库镜像。排查首先ping www.baidu.com测试外网是否通。如果不通检查/etc/resolv.conf文件中的DNS配置。检查网络服务是否正常systemctl status network(CentOS 7) 或systemctl status NetworkManager。解决如果是DNS问题修改/etc/resolv.conf添加可靠的DNS如nameserver 8.8.8.8。如果是YUM源问题可以尝试更换为国内镜像源如阿里云、腾讯云镜像。备份原repo文件后下载新的repo文件。问题二./configure阶段报错例如the HTTP rewrite module requires the PCRE library原因这是最典型的依赖库缺失错误。虽然我们脚本里用yum install pcre-devel安装了但有时库文件路径未被编译器找到或者版本不兼容。排查确认包是否真的安装成功rpm -qa | grep pcre-devel。查找库文件位置find /usr -name \libpcre.*\。解决如果未安装手动安装yum install -y pcre-devel openssl-devel zlib-devel。如果已安装但仍报错可能是开发库-devel包没装确保安装的是pcre-devel而不仅仅是pcre。极少数情况需要指定库路径可以在./configure时加上--with-pcre/usr/lib64具体路径根据find结果调整。问题三make编译阶段报错大量undefined reference to ...原因通常是链接阶段出了问题可能是库顺序不对或者缺少某个核心库。在Nginx编译中相对少见但在一些极端自定义编译时可能出现。解决这通常需要调整编译参数。一个比较彻底的方法是清理旧的编译对象再重试make clean ./configure ... 你的参数 make如果问题依旧尝试简化./configure参数只保留最必要的模块看是否能通过。问题四脚本执行成功但systemctl start nginx失败原因服务启动失败的原因很多必须查看详细日志。排查查看服务状态systemctl status nginx -l这里会显示简短的错误信息。查看详细日志journalctl -xe -u nginx这是排查Systemd服务问题的利器会输出从启动到失败的全过程日志。测试配置文件手动执行${INSTALL_DIR}/sbin/nginx -t检查Nginx配置文件语法是否正确。脚本中ExecStartPre已经做了这个但手动执行可以看得更清楚。检查端口占用netstat -tlnp | grep :80看80端口是否被其他程序如Apache、其他Nginx实例占用。检查SELinux在某些严格的安全策略下SELinux会阻止Nginx绑定端口。临时禁用测试setenforce 0然后再启动服务。如果成功说明是SELinux问题需要为Nginx添加正确的上下文规则或放行端口而不是永久关闭SELinux。解决根据日志对症下药。如果是配置文件错误修改${INSTALL_DIR}/conf/nginx.conf。如果是端口占用停用占用程序或修改Nginx监听端口。如果是SELinux使用semanage和setsebool命令进行配置。问题五防火墙和SELinux的“隐形墙”这是新手最容易忽略的两大安全屏障经常导致“本地curl能通外网访问不了”。防火墙脚本已尝试配置firewalld。如果你用的是iptables需要手动添加规则iptables -I INPUT -p tcp --dport 80 -j ACCEPT iptables -I INPUT -p tcp --dport 443 -j ACCEPT service iptables save # 保存规则SELinux如果怀疑是SELinux可以临时设置为宽容模式测试setenforce 0如果问题解决永久关闭不推荐可以修改/etc/selinux/config中SELINUXdisabled。推荐的做法是添加正确的SELinux规则# 允许Nginx网络连接 setsebool -P httpd_can_network_connect 1 # 或者针对特定端口 semanage port -a -t http_port_t -p tcp 8080 # 如果你的Nginx监听80805. 超越“一键”脚本的优化与定制思路上面的脚本已经是一个功能完整的生产级脚本。但我们可以让它更强大、更灵活。5.1 增加版本参数化让脚本可以通过命令行参数指定版本而不是硬编码在脚本里。#!/bin/bash # 在脚本开头添加参数解析 NGINX_VERSION1.19.6 # 默认版本 while [[ $# -gt 0 ]]; do case $1 in -v|--version) NGINX_VERSION$2 shift 2 ;; *) log_error 未知参数: $1 ;; esac done log_info 准备安装 Nginx 版本: ${NGINX_VERSION} # 后续的 NGINX_SOURCE_URL 等变量会使用这个 NGINX_VERSION使用方式./install_nginx.sh --version 1.20.15.2 集成更安全的哈希校验使用SHA256校验替代MD5并自动从官网获取校验值如果官网提供的话。# 在变量定义部分 NGINX_SHA256_URLhttp://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz.sha256 # 在 download_and_extract 函数中下载后添加 log_info 正在校验文件完整性... wget -O ${source_file}.sha256 ${NGINX_SHA256_URL} if sha256sum -c ${source_file}.sha256; then log_info SHA256 校验通过。 else log_error SHA256 校验失败文件可能已损坏或被篡改。 fi5.3 实现真正的“幂等性”与回滚更高级的脚本应该能检测当前已安装的Nginx版本和配置。如果版本相同则跳过编译安装只更新服务文件或配置。如果安装失败能自动清理已安装的部分文件或提供回滚到之前版本的能力。这需要更复杂的逻辑例如在安装前备份现有版本记录安装日志在错误时触发清理函数。5.4 适配不同Linux发行版脚本目前只支持CentOS。可以增加OS检测逻辑对Ubuntu/Debian使用apt-get对Alibaba Cloud Linux、Anolis OS等兼容CentOS的发行版做适配判断。check_os_and_install_deps() { if [ -f /etc/redhat-release ]; then # CentOS/RHEL/AlmaLinux/Rocky Linux 逻辑 yum install -y ... elif [ -f /etc/debian_version ]; then # Debian/Ubuntu 逻辑 apt-get update apt-get install -y build-essential libpcre3-dev zlib1g-dev libssl-dev wget else log_error 不支持的操作系统。 fi }5.5 将脚本转化为Ansible Role或Terraform Module对于大规模基础设施“一键脚本”最终会进化成配置管理代码。你可以将上述逻辑编写成Ansible的Task或者Terraform的provisioner实现声明式、可版本化、可测试的自动化部署。这是运维自动化的更高阶段。从一行行手动输入命令到一个健壮的Shell脚本再到可配置、可扩展的自动化代码这个过程本身就是运维工程师能力成长的缩影。这个为CentOS安装Nginx 1.19.6的脚本不仅是一个工具更是一个理解Linux服务部署、自动化思想和问题排查方法的绝佳范例。下次当你需要部署其他服务时不妨也试着用这样的思路先拆解再封装最终收获一个属于你自己的、可靠的“一键”解决方案。