如何构建支持 ngx_http_lua_module 的 ARM64 架构 Nginx Dockerfile?
摘要:一、📘 背景 ngx_http_lua_module 是 OpenResty 的核心模块之一,使 Nginx 可以直接执行 Lua 脚本,实现灵活的动态逻辑处理,例如: 动态负载均衡 请求内容过滤 动态缓存控
一、📘 背景
ngx_http_lua_module 是 OpenResty 的核心模块之一,使 Nginx 可以直接执行 Lua 脚本,实现灵活的动态逻辑处理,例如:
动态负载均衡
请求内容过滤
动态缓存控制
自定义鉴权逻辑
官方的 Nginx 镜像默认 不包含 Lua 支持,因此需要通过编译源码的方式添加。
二、🧩 编译所需组件
编译时需要以下依赖:
依赖包
说明
build-essential
基础编译工具(gcc、make 等)
libpcre3 / libpcre3-dev
Nginx 正则匹配模块依赖
zlib1g / zlib1g-dev
Nginx 压缩模块依赖
openssl / libssl-dev
HTTPS 支持
wget / git
下载源码
gettext-base
提供 envsubst 命令用于模板变量替换
额外依赖组件:
组件
说明
LuaJIT
高性能 Lua 虚拟机,Nginx 的 Lua 模块依赖它
lua-nginx-module
Nginx 与 LuaJIT 的集成模块
lua-resty-core / lua-resty-lrucache
OpenResty 常用 Lua 库(必须安装,否则报 “resty.core not found”)
三、🛠️ Dockerfile 分为两阶段
第一阶段:编译(builder)
第二阶段:运行时(runtime)
✅ 第一阶段:编译阶段(builder)
目标:在 arm64v8/ubuntu:22.04 上编译 Nginx + Lua 模块。
# =========================
# Builder
# =========================
FROM arm64v8/ubuntu:22.04 AS builder
RUN apt-get update && apt-get install -y \
build-essential \
libpcre3 libpcre3-dev \
zlib1g zlib1g-dev \
openssl libssl-dev \
wget git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /opt
ENV NGINX_VERSION=1.24.0
ENV LUAJIT_VERSION=2.1-20230410
ENV LUA_MODULE_VERSION=0.10.29
# 下载 Nginx
RUN wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \
tar -zxvf nginx-${NGINX_VERSION}.tar.gz
# 编译 LuaJIT
RUN git clone https://github.com/openresty/luajit2.git -b v${LUAJIT_VERSION} && \
cd luajit2 && make && make install
# 下载 lua-nginx-module
RUN git clone https://github.com/openresty/lua-nginx-module.git -b v${LUA_MODULE_VERSION}
# 下载并安装 lua-resty-core 和 lua-resty-lrucache
RUN git clone https://github.com/openresty/lua-resty-core.git /opt/lua-resty-core && \
git clone https://github.com/openresty/lua-resty-lrucache.git /opt/lua-resty-lrucache && \
mkdir -p /usr/local/share/lua/5.1/resty && \
cp -r /opt/lua-resty-core/lib/resty/* /usr/local/share/lua/5.1/resty/ && \
cp -r /opt/lua-resty-lrucache/lib/resty/* /usr/local/share/lua/5.1/resty/
# 环境变量
ENV LUAJIT_LIB=/usr/local/lib
ENV LUAJIT_INC=/usr/local/include/luajit-2.1
WORKDIR /opt/nginx-${NGINX_VERSION}
# 编译 Nginx + Lua 模块,路径改为 /etc/nginx
RUN ./configure \
--prefix=/etc/nginx \
--sbin-path=/etc/nginx/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/etc/nginx/logs/error.log \
--http-log-path=/etc/nginx/logs/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-cc-opt="-O2 -I${LUAJIT_INC}" \
--with-ld-opt="-L${LUAJIT_LIB} -Wl,-rpath,${LUAJIT_LIB}" \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-threads \
--with-http_stub_status_module \
--add-module=/opt/lua-nginx-module \
&& make -j$(nproc) \
&& make install
✅ 第二阶段:运行时阶段(runtime)
目标:生成体积更小、运行时可直接使用的镜像。
# =========================
# Runtime image
# =========================
FROM arm64v8/ubuntu:22.04
RUN apt-get update && apt-get install -y \
libpcre3 zlib1g openssl gettext-base \
&& rm -rf /var/lib/apt/lists/*
# 创建 nginx 用户和组
RUN groupadd -r nginx && useradd -r -g nginx nginx \
&& mkdir -p /var/log/nginx \
&& chown -R nginx:nginx /var/log/nginx
# 拷贝 Nginx 安装目录和 Lua 库
COPY --from=builder /etc/nginx /etc/nginx
COPY --from=builder /usr/local/lib/libluajit-5.1.so* /usr/local/lib/
COPY --from=builder /usr/local/share/lua/5.1 /usr/local/share/lua/5.1
ENV PATH=/etc/nginx/sbin:$PATH
ENV LD_LIBRARY_PATH=/usr/local/lib
# 暴露端口
EXPOSE 80 443
# 默认命令
CMD ["nginx", "-g", "daemon off;"]
四、📂 目录结构说明
编译完成后 /etc/nginx 目录结构:
/etc/nginx/
├── sbin/nginx # Nginx 可执行文件
├── conf/nginx.conf # 主配置文件
├── logs/ # 日志目录
└── modules/ # 可选的动态模块目录
Lua 相关模块位置:
/usr/local/share/lua/5.1/resty/
├── core/
├── lrucache/
└── ...
五、⚙️ 验证 Lua 模块是否生效
进入容器后执行:
nginx -V 2>&1 | grep lua
输出应包含:
--add-module=/opt/lua-nginx-module
再创建测试配置 /etc/nginx/conf.d/lua_test.conf:
server {
listen 80;
location /lua {
default_type text/plain;
content_by_lua_block {
ngx.say("Hello from Lua in ARM64 Nginx!")
}
}
}
启动 nginx 后访问 /lua,应输出:
Hello from Lua in ARM64 Nginx!
六、🧰 常见问题与解决方案
错误信息
原因
解决方案
ngx_http_lua_module requires LuaJIT 2.x
LuaJIT 未安装或版本错误
确认 LUAJIT_INC 与 LUAJIT_LIB 环境变量设置正确
resty.core not found
没有安装 lua-resty-core
手动拷贝 core 与 lrucache 到 /usr/local/share/lua/5.1/resty
nginx: [emerg] getpwnam("nginx") failed
配置中使用 user nginx; 但用户不存在
Dockerfile 中添加 useradd -r nginx
could not open error log file
/var/log/nginx 目录不存在或无权限
创建目录并设置权限
/usr/sbin/nginx: not found
PATH 或编译路径不一致
使用 --sbin-path=/etc/nginx/sbin/nginx 并更新 PATH
七、🚀 构建与运行
# 构建镜像
docker build -t nginx-lua:arm64 .
# 启动容器
docker run -d -p 8080:80 nginx-lua:arm64
# 测试访问
curl http://localhost:8080/lua
输出:
Hello from Lua in ARM64 Nginx!
八、🌟 进阶优化建议
可选优化:多阶段裁剪镜像
使用 FROM arm64v8/alpine 作为 runtime 基础镜像,体积更小;
但需要手动安装 musl 编译 LuaJIT,过程略复杂。
可选优化:OpenResty 替代方案
如果目标仅是使用 Lua,可以直接用 openresty/openresty:arm64 镜像;
该镜像内置所有 Lua 模块,无需自己编译。
环境变量模板渲染
可使用 envsubst 在容器启动时自动替换 Nginx 配置中的变量。
✅ 总结
模块
路径
说明
Nginx 主目录
/etc/nginx
标准安装目录
Nginx 二进制
/etc/nginx/sbin/nginx
执行文件路径
LuaJIT 库
/usr/local/lib/libluajit-5.1.so
动态链接库
Lua 脚本库
/usr/local/share/lua/5.1/resty/
Lua 模块代码
日志路径
/var/log/nginx/
需确保 nginx 用户可写
