ARM64 架构下编译支持 ngx_http_lua_module 的 Nginx —— Dockerfile 实践
🧾 ARM64 架构下编译支持 ngx_http_lua_module 的 Nginx —— Dockerfile 实践
一、📘 背景
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 模块,无需自己编译。
- 如果目标仅是使用 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 用户可写 |

浙公网安备 33010602011771号