Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

nginx LuaJIT Docker License Status

Русский | English


nginx + Lua (OpenResty-стек), собранный из исходников

Многостадийный Docker-образ с nginx, скомпилированным из исходников вместе с модулем lua-nginx-module на движке LuaJIT. Проект демонстрирует сборку C-проектов из исходников, разрешение зависимостей между компонентами и оптимизацию итогового образа через multi-stage build.

Что внутри

Компонент Версия Назначение
nginx 1.30.3 Веб-сервер, собран с --with-http_ssl_module
LuaJIT (OpenResty fork) 2.1-20250826 JIT-компилятор Lua - обязателен для lua-nginx-module
ngx_devel_kit (NDK) 0.3.4 Инфраструктурный модуль, от которого зависит lua-модуль
lua-nginx-module 0.10.29 Встраивает Lua в конфигурацию nginx (content_by_lua_block и др.)
lua-resty-core 0.1.32 Обязательная Lua-обвязка поверх FFI (без неё nginx с lua-модулем не стартует)
lua-resty-lrucache 0.15 LRU-кэш, зависимость resty-core

Версии компонентов согласованы между собой - это критично: lua-nginx-module требует именно OpenResty-форк LuaJIT (ванильный LuaJIT не подходит), а lua-resty-core жёстко привязан к версии lua-модуля.

Архитектура сборки

Стадия 1 - builder

  • Устанавливаются компилятор и dev-заголовки (libpcre2-dev, zlib1g-dev, libssl-dev).
  • LuaJIT собирается из исходников и устанавливается в /usr/local; пути передаются в сборку nginx через переменные окружения LUAJIT_LIB и LUAJIT_INC.
  • nginx конфигурируется с двумя внешними модулями через --add-module (статическая линковка) и собирается параллельно (make -j$(nproc)).
  • Устанавливаются Lua-библиотеки resty-core и lrucache в стандартный путь package.path (/usr/local/share/lua/5.1).

Стадия 2 - final

В итоговый образ попадают только артефакты сборки и runtime-библиотеки (libpcre2-8-0, zlib1g, libssl3) — без компилятора, заголовков и исходников:

  • /usr/local/nginx - собранный nginx;
  • /usr/local/lib - каталог копируется целиком, чтобы сохранились симлинки libluajit-5.1.so.2 → libluajit-5.1.so.2.1.x;
  • /usr/local/share/lua - Lua-библиотеки resty-core и lrucache;
  • ldconfig обновляет кэш динамического линковщика, иначе nginx не найдёт libluajit в нестандартном /usr/local/lib.

Дополнительно: STOPSIGNAL SIGQUIT - graceful shutdown nginx (доработка активных соединений вместо мгновенного обрыва по SIGTERM).

Запуск

docker build -t nginx-lua .
docker run -d -p 8080:80 --name nginx-lua nginx-lua

Проверка:

curl http://localhost:8080/
# It works

curl http://localhost:8080/proof
# Lua computed: 2+2 = 4
# LuaJIT engine: LuaJIT 2.1.xxxxxxx
# ngx_lua version: 10029

Эндпоинт /proof подтверждает, что Lua-код действительно исполняется внутри nginx: выводит результат вычисления, версию JIT-движка и версию ngx_lua.

Структура репозитория

.
├── Dockerfile   # двухстадийная сборка: builder → final
├── nginx.conf   # конфиг с content_by_lua_block
└── README.md

Ключевые решения

  • Multi-stage build. Тулчейн сборки (~сотни МБ: gcc, make, dev-пакеты) остаётся в стадии builder; финальный образ содержит только бинарники и три runtime-библиотеки.
  • Pinned-версии через ARG. Все версии вынесены в аргументы сборки в одном месте - образ воспроизводим.
  • Совместимость компонентов. Стек nginx + Lua требует строгого соответствия версий четырёх взаимозависимых проектов; несовпадение проявляется либо ошибкой линковки, либо падением на старте с сообщением от resty-core.
  • Слои и кэш. LuaJIT, nginx с модулями и Lua-библиотеки собираются в отдельных RUN-слоях - при смене версии одного компонента пересобирается только его слой.
  • Гигиена образа. --no-install-recommends, очистка apt-списков, копирование каталога /usr/local/lib целиком ради сохранения симлинков вместо поштучного копирования файлов.


nginx + Lua (OpenResty stack), built from source

Русский | English

A multi-stage Docker image with nginx compiled from source together with the lua-nginx-module on the LuaJIT engine. The project demonstrates building C projects from source, resolving dependencies between components, and shrinking the final image with a multi-stage build.

What's inside

Component Version Purpose
nginx 1.30.3 Web server, built with --with-http_ssl_module
LuaJIT (OpenResty fork) 2.1-20250826 Lua JIT compiler — required by lua-nginx-module
ngx_devel_kit (NDK) 0.3.4 Infrastructure module that the Lua module depends on
lua-nginx-module 0.10.29 Embeds Lua into the nginx configuration (content_by_lua_block, etc.)
lua-resty-core 0.1.32 Mandatory Lua binding on top of FFI (nginx with the Lua module won't start without it)
lua-resty-lrucache 0.15 LRU cache, a dependency of resty-core

The component versions are aligned with one another — and this is critical: lua-nginx-module requires the OpenResty fork of LuaJIT specifically (vanilla LuaJIT does not work), and lua-resty-core is tightly pinned to the version of the Lua module.

Build architecture

Stage 1 — builder

  • The compiler and dev headers (libpcre2-dev, zlib1g-dev, libssl-dev) are installed.
  • LuaJIT is built from source and installed into /usr/local; the paths are passed to the nginx build through the LUAJIT_LIB and LUAJIT_INC environment variables.
  • nginx is configured with two external modules via --add-module (static linking) and built in parallel (make -j$(nproc)).
  • The Lua libraries resty-core and lrucache are installed into the standard package.path (/usr/local/share/lua/5.1).

Stage 2 — final

Only the build artifacts and runtime libraries (libpcre2-8-0, zlib1g, libssl3) end up in the final image — without the compiler, headers, or sources:

  • /usr/local/nginx — the built nginx;
  • /usr/local/lib — the directory is copied as a whole so the libluajit-5.1.so.2 → libluajit-5.1.so.2.1.x symlinks are preserved;
  • /usr/local/share/lua — the resty-core and lrucache Lua libraries;
  • ldconfig refreshes the dynamic linker cache, otherwise nginx won't find libluajit in the non-standard /usr/local/lib.

In addition: STOPSIGNAL SIGQUIT — graceful shutdown of nginx (draining active connections instead of an instant termination on SIGTERM).

Running it

docker build -t nginx-lua .
docker run -d -p 8080:80 --name nginx-lua nginx-lua

Check:

curl http://localhost:8080/
# It works

curl http://localhost:8080/proof
# Lua computed: 2+2 = 4
# LuaJIT engine: LuaJIT 2.1.xxxxxxx
# ngx_lua version: 10029

The /proof endpoint confirms that the Lua code really executes inside nginx: it prints the computed result, the JIT engine version, and the ngx_lua version.

Repository structure

.
├── Dockerfile   # two-stage build: builder → final
├── nginx.conf   # config with content_by_lua_block
└── README.md

Key decisions

  • Multi-stage build. The build toolchain (~hundreds of MB: gcc, make, dev packages) stays in the builder stage; the final image contains only the binaries and three runtime libraries.
  • Pinned versions via ARG. All versions are hoisted into build arguments in a single place — the image is reproducible.
  • Component compatibility. The nginx + Lua stack requires strict version alignment across four interdependent projects; a mismatch surfaces either as a linker error or as a crash on startup with a message from resty-core.
  • Layers and cache. LuaJIT, nginx with its modules, and the Lua libraries are built in separate RUN layers — when one component's version changes, only its layer is rebuilt.
  • Image hygiene. --no-install-recommends, cleanup of apt lists, and copying the whole /usr/local/lib directory to preserve symlinks instead of copying files one by one.

About

Многостадийная Docker-сборка nginx из исходников с LuaJIT и lua-nginx-module

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages