Dockerfile编译Nginx指定--add-module后模块未生成启动报错
问题原因
- 核心问题是混淆了Nginx静态模块与动态模块的编译参数:你在
./configure阶段使用的--add-module是静态模块编译参数,该参数会将第三方模块的代码直接编译进Nginx主二进制文件/usr/sbin/nginx,不会生成独立的.so动态库文件。这种场景下make install阶段既不会创建/etc/nginx/modules目录,也不会生成任何模块文件,和你排查到的现象完全一致。 - 你的
nginx.conf开头配置了load_module "/etc/nginx/modules/ngx_http_js_module.so";这类动态模块加载指令,Nginx启动时会按路径查找对应so文件,自然会抛出文件不存在的错误。
解决方法
两种方案按需选择即可:
方案1:沿用静态编译(改动最小)
直接删除nginx.conf中所有加载ngx_http_js_module、ngx_http_redis2_module的load_module指令。两个模块已经被静态编译进Nginx二进制,不需要额外加载,直接在配置中使用模块提供的指令即可正常运行。
编译结果可以在容器内执行nginx -V验证,输出的configure参数中如果包含你添加的两个--add-module配置,就说明模块编译成功。
方案2:改用动态模块编译(匹配现有load_module配置)
修改Dockerfile中configure命令的参数,将静态编译标识--add-module替换为动态编译标识--add-dynamic-module,修改后的命令如下:
./configure --prefix=/etc/nginx --modules-path=/etc/nginx/modules --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --add-dynamic-module=redis2-nginx-module --add-dynamic-module=njs/nginx
修改后重新构建镜像,make install阶段会自动创建/etc/nginx/modules目录,并将编译生成的ngx_http_js_module.so、ngx_http_redis2_module.so等模块文件拷贝到该目录,原有配置中的load_module指令即可正常加载模块。
可选优化建议
你当前的Dockerfile存在构建层数多、镜像体积冗余的问题,可以调整优化:
- 合并同类型RUN指令,减少镜像层数量
- apt安装时添加
--no-install-recommends参数,避免安装非必要依赖,安装完成后清理apt缓存 - 编译完成后删除源码包、编译依赖,减小最终镜像体积
以动态编译方案为例,优化后的Dockerfile如下:
FROM ubuntu:latest RUN apt-get update && apt-get install -y --no-install-recommends \ wget \ git \ gcc \ make \ libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev \ mercurial \ && rm -rf /var/lib/apt/lists/* RUN wget 'http://nginx.org/download/nginx-1.21.6.tar.gz' \ && tar -xzvf nginx-1.21.6.tar.gz \ && rm nginx-1.21.6.tar.gz WORKDIR nginx-1.21.6 RUN hg clone http://hg.nginx.org/njs \ && git clone https://github.com/openresty/redis2-nginx-module \ && ./configure --prefix=/etc/nginx --modules-path=/etc/nginx/modules --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --add-dynamic-module=redis2-nginx-module --add-dynamic-module=njs/nginx \ && make -j2 \ && make install \ && rm -rf /nginx-1.21.6 COPY /nginx /etc/nginx EXPOSE 80 ENTRYPOINT ["nginx", "-g", "daemon off;"]
内容的提问来源于stack exchange,提问作者Danil Giniyatullin
相关产品推荐
相关产品推荐

