环境:Debian 13 Nginx1.31.1
nano auto_zstd_nginx.sh
#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: auto_zstd_nginx.sh
# 适用系统: Debian 12/13 / Ubuntu
# 功能描述: 具备智能缓存检测的全功能 Nginx Zstd 动态模块编译与全自动更新脚本
# ==============================================================================
set -e # 遇到致命错误立即停止执行
# 颜色输出定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO] $1${NC}"; }
log_warn() { echo -e "${YELLOW}[WARN] $1${NC}"; }
log_err() { echo -e "${RED}[ERROR] $1${NC}"; exit 1; }
SRC_DIR="/usr/src"
CACHE_META="${SRC_DIR}/.nginx_zstd_cache.meta"
MODULES_INSTALL_DIR="/usr/lib/nginx/modules"
# 1. 权限检查
if [ "$EUID" -ne 0 ]; then
log_err "请使用 root 用户或通过 sudo 运行此脚本!"
fi
# 2. 检测当前运行的 Nginx 状态
if ! command -v nginx &> /dev/null; then
log_err "未检测到系统安装了 Nginx,请先安装 Nginx 主程序!"
fi
# 动态提取当前 Nginx 版本号 (例如: 1.31.0)
NGINX_VER=$(nginx -v 2>&1 | awk -F/ '{print $2}' | cut -d' ' -f1)
NGINX_ARGS=$(nginx -V 2>&1 | grep "configure arguments:" | sed 's/configure arguments://')
log_info "当前系统运行的 Nginx 版本: ${NGINX_VER}"
# 自动修正模块安装路径
if [ ! -d "$MODULES_INSTALL_DIR" ]; then
MODULES_INSTALL_DIR="/etc/nginx/modules"
fi
# 3. 智能检测远端 Zstd 库的最新版本(无需提前克隆)
log_info "正在检测 Facebook Zstd 官方仓库最新动态..."
if ! command -v git &> /dev/null; then
# 如果没有 git,临时安装以便检测
apt-get update -y || true
apt-get install -y git wget awk
fi
# 获取远程最新 Commit ID
REMOTE_ZSTD_COMMIT=$(git ls-remote https://github.com/facebook/zstd.git HEAD | awk '{print $1}')
if [ -z "$REMOTE_ZSTD_COMMIT" ]; then
log_err "无法连接到 GitHub 获取 Zstd 版本,请检查网络连接。"
fi
# 4. 缓存验证:比对版本与文件完整性
NEED_BUILD_ZSTD=true
NEED_BUILD_MODULE=true
if [ -f "$CACHE_META" ]; then
# 读取缓存的元数据
# shellcheck disable=SC1090
source "$CACHE_META"
# 检查本地动态库文件是否存在
if [ -f "/usr/local/lib/libzstd.so" ] && [ "$LAST_ZSTD_COMMIT" == "$REMOTE_ZSTD_COMMIT" ]; then
NEED_BUILD_ZSTD=false
log_info "✨ 检测到本地 Zstd 核心库已是最新版本 (${REMOTE_ZSTD_COMMIT:0:7}),跳过拉取与编译。"
fi
# 检查 Nginx 动态模块文件是否存在并比对版本
if [ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_filter_module.so" ] && \
[ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_static_module.so" ] && \
[ "$LAST_NGINX_VER" == "$NGINX_VER" ] && \
[ "$NEED_BUILD_ZSTD" == "false" ]; then
NEED_BUILD_MODULE=false
fi
fi
# 如果一切都未改变,直接退出
if [ "$NEED_BUILD_ZSTD" == "false" ] && [ "$NEED_BUILD_MODULE" == "false" ]; then
log_info "🚀 [完美缓存] 当前 Nginx 编译环境与 Zstd 模块均无任何更新,无需重复编译!"
exit 0
fi
# 5. 解决 APT 签名错误并安装依赖
log_info "正在准备同步系统依赖包..."
# 核心容错:使用 || true 允许非关键性源(如 MySQL 签名过期)报错,不中断脚本
apt-get update -y || log_warn "部分第三方软件源同步失败(例如系统的 MySQL 密钥未找到),脚本将忽略并尝试继续..."
log_info "正在安装与更新必要的编译工具链..."
apt-get install -y build-essential git libpcre3-dev zlib1g-dev libssl-dev debhelper wget
# 如果系统残留了旧的发行版自带库,予以清除以防冲突
if dpkg -l | grep -q libzstd-dev; then
log_warn "清理系统自带的旧版 libzstd-dev 以防链路冲突..."
apt-get remove -y libzstd-dev libzstd1 || true
fi
# 6. 【按需编译】最新的 Zstd 核心库
cd ${SRC_DIR}
if [ "$NEED_BUILD_ZSTD" == "true" ]; then
log_info "正在下载/更新 Zstd 官方源码并进行编译..."
if [ ! -d "zstd" ]; then
git clone --depth 1 https://github.com/facebook/zstd.git
fi
cd zstd
git fetch --depth 1 origin
git reset --hard origin/dev || git reset --hard origin/master # 适配官方默认主分支
log_info "开始编译 Zstd 核心库..."
make -j$(nproc)
make install
ldconfig
log_info "Zstd 核心库编译并安装成功。"
fi
# 7. 【按需编译】Nginx Zstd 动态模块
cd ${SRC_DIR}
if [ "$NEED_BUILD_MODULE" == "true" ]; then
log_info "正在同步 Nginx 源码与动态模块源码..."
# 清理旧的 Nginx 源码目录确保干净编译
rm -rf "nginx-${NGINX_VER}" "nginx-${NGINX_VER}.tar.gz"
wget -c "http://nginx.org/download/nginx-${NGINX_VER}.tar.gz"
tar -zxf "nginx-${NGINX_VER}.tar.gz"
if [ ! -d "zstd-nginx-module" ]; then
git clone https://github.com/tokers/zstd-nginx-module.git
fi
cd zstd-nginx-module && git pull && cd ..
log_info "配置 Nginx 模块环境,无缝继承原生 Nginx 编译参数..."
cd "nginx-${NGINX_VER}"
# 注入原生参数与定制的 Zstd include 路径
eval "./configure ${NGINX_ARGS} --add-dynamic-module=${SRC_DIR}/zstd-nginx-module --with-cc-opt='-I/usr/local/include' --with-ld-opt='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'"
log_info "并行编译 Nginx Zstd 动态模块..."
make modules
log_info "将编译产物自动替换至 Nginx 目录..."
mkdir -p ${MODULES_INSTALL_DIR}
cp objs/ngx_http_zstd_filter_module.so ${MODULES_INSTALL_DIR}/
cp objs/ngx_http_zstd_static_module.so ${MODULES_INSTALL_DIR}/
chmod 644 ${MODULES_INSTALL_DIR}/ngx_http_zstd_*.so
# 检查模块语法
if nginx -t &>/dev/null; then
log_info "Nginx 配置文件语法检查通过,正在平滑重启服务..."
systemctl reload nginx || log_warn "Nginx 重载失败,请手动检查系统服务状态。"
else
log_warn "检测到 Nginx 配置当前存在异常,未自动重载,请执行 'nginx -t' 排查。"
fi
fi
# 8. 写入/更新本地编译缓存元数据
cat > "$CACHE_META" <<EOF
LAST_NGINX_VER="${NGINX_VER}"
LAST_ZSTD_COMMIT="${REMOTE_ZSTD_COMMIT}"
EOF
log_info "=================================================="
log_info "🎉 全功能自动 Nginx Zstd 模块部署/更新任务成功完成!"
log_info "当前缓存状态:Nginx [${NGINX_VER}] | Zstd [${REMOTE_ZSTD_COMMIT:0:7}]"
log_info "=================================================="
chmod +x auto_zstd_nginx.sh
# 执行两次测试版本缓存
sudo ./auto_zstd_nginx.sh