为 OpenResty 添加 Brotli 模块,使其支持Brotli压缩/解压(ARM64 Ubuntu 完整踩坑记录)
起因,使用 1panel 面板安装 openresty 进行加速(反代缓存)某一网站,由于该网站启用了 br 压缩,导致 css 文件中的字符串无法替换,openresty 需要 ngx_brotli 才可以启用 br 压缩支持,故编译了一下这个模块,使其支持
一、背景
某资源域名默认启用 Brotli 压缩(br)。
在反向代理场景下,如果想用 sub_filter 替换 CSS 里的字体路径,必须让 Nginx 先解压 → 修改 → 再输出明文。
官方 OpenResty 镜像(包括 1Panel 封装)并未携带 Brotli 模块,需要自行编译动态模块 .so。
本文记录在 ARM64 Ubuntu 20.04 下,为 Docker 内 OpenResty 1.27.1 编译并启用 Brotli 的完整流程,可直接复刻到 CI/CD。
非 Docker 同理。
二、环境信息
| 组件 | 版本 |
|---|---|
| 宿主机 | Ubuntu 20.04 ARM64 |
| Docker 镜像 | openresty/openresty:1.27.1.2-2-1-focal |
| Nginx 核心 | 1.27.1 |
| Brotli 模块 | github.com/google/ngx_brotli(main) |
三、编译步骤(宿主机或容器内均可)
1. 安装依赖
sudo apt update
sudo apt install -y git cmake build-essential libpcre3-dev zlib1g-dev libssl-dev libbrotli-dev2. 拉取模块源码
git clone --recurse-submodules https://github.com/google/ngx_brotli.git /root/nginx1.27.1/ngx_brotli3. 下载与运行版本一致的 Nginx 源码
# 查看容器内版本
docker exec <容器> nginx -v
# nginx version: nginx/1.27.1
wget https://nginx.org/download/nginx-1.27.1.tar.gz -O /root/nginx1.27.1/nginx.tar.gz
tar -xf /root/nginx1.27.1/nginx.tar.gz -C /root/nginx1.27.1 && cd /root/nginx1.27.1/nginx-1.27.14. 配置并编译动态模块
./configure --with-compat --add-dynamic-module=/root/nginx1.27.1/ngx_brotli
make modules # 1.9.11+ 专用快捷目标成功输出:
objs/ngx_http_brotli_filter_module.so
objs/ngx_http_brotli_static_module.so四、引用模块
Docker 中引用模块
查看 docker 容器的名称,如果使用的 1panel 直接在后台页面就能查看容器名称
如果没有面板或使用的其他面板请自行查找容器名称
比如此处 OpenResty 的容器名称为 1Panel-openresty-L0Pv
编译好的文件存放在 /root/nginx-1.27.1/nginx-1.27.1/objs 中
连接到服务器,将模块文件复制到 Docker 容器内。
export CONTAINER_NAME=1Panel-openresty-L0Pv
export BROTLI_FILES=/root/nginx-1.27.1/nginx-1.27.1/objs
docker cp "$BROTLI_FILES/ngx_http_brotli_filter_module.so" "$CONTAINER_NAME:/usr/local/openresty/nginx/modules/ngx_http_brotli_filter_module.so"
docker cp "$BROTLI_FILES/ngx_http_brotli_static_module.so" "$CONTAINER_NAME:/usr/local/openresty/nginx/modules/ngx_http_brotli_static_module.so"
其他方式引用模块
如果是可执行文件,或其他方式,参考上述步骤
五、启用模块
Docker 中启用模块
如果是 1panel 安装的 openresty,在1Panel的面板中进入配置文件目录 /opt/1panel/apps/openresty/openresty/conf ,编辑 nginx.conf 文件
在 nginx.conf 顶部(events 之前)如下代码:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
同时在 http 中加入 brotli 的配置代码:
brotli on;
brotli_comp_level 9;
brotli_static on;
brotli_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml
application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype
application/x-font-ttf application/x-javascript application/xhtml+xml application/xml
font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon
image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;
六、验证
注意修改容器名称,我这里是 1Panel-openresty-L0Pv ,其他名称需要替换
# 容器内检查
docker exec 1Panel-openresty-L0Pv nginx -t # test is successful
# 客户端验证
curl -I -H "Accept-Encoding: br" \
https://your.cdn/xxx/assets/site.css响应头出现:
content-encoding: br同时 CSS 内路径已能被查找替换。
七、常见报错速查
| 现象 | 原因 | 解决 |
|---|---|---|
unknown directive "brotli" | 未加载 .so | 顶部 load_module |
dlopen() ... .so: cannot open shared object file | 文件不存在/架构不符 | 确认 .so 已复制且 arm64 |
make: *** No rule to make target 'modules' | 未生成 Makefile | 先 apt install libpcre3-dev 再 ./configure |
sub_filter 不生效 | 后端返回 br/gzip | 用 gunzip on; brotli on; 先解压 |
八、小结
- ARM64 下 没有官方预编译 Brotli 模块;
- 用 与运行版本一致的 Nginx 源码 +
--with-compat即可产出动态.so; - 编译完复制到容器,两行
load_module即可启用; - 结合
gunzip/brotli模块,可在反向代理中随意修改 原本被压缩的文本流。
至此,Brotli 压缩 + 路径替换 全链路打通,资源加速完成 ✅
评论 (0)