Русский | English
Многостадийный 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-модуля.
- Устанавливаются компилятор и 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).
В итоговый образ попадают только артефакты сборки и 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целиком ради сохранения симлинков вместо поштучного копирования файлов.
Русский | 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.
| 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.
- 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 theLUAJIT_LIBandLUAJIT_INCenvironment variables. - nginx is configured with two external modules via
--add-module(static linking) and built in parallel (make -j$(nproc)). - The Lua libraries
resty-coreandlrucacheare installed into the standardpackage.path(/usr/local/share/lua/5.1).
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 thelibluajit-5.1.so.2 → libluajit-5.1.so.2.1.xsymlinks are preserved;/usr/local/share/lua— the resty-core and lrucache Lua libraries;ldconfigrefreshes the dynamic linker cache, otherwise nginx won't findlibluajitin the non-standard/usr/local/lib.
In addition: STOPSIGNAL SIGQUIT — graceful shutdown of nginx (draining active connections instead of an instant termination on SIGTERM).
docker build -t nginx-lua .
docker run -d -p 8080:80 --name nginx-lua nginx-luaCheck:
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: 10029The /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.
.
├── Dockerfile # two-stage build: builder → final
├── nginx.conf # config with content_by_lua_block
└── README.md
- 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
RUNlayers — when one component's version changes, only its layer is rebuilt. - Image hygiene.
--no-install-recommends, cleanup ofaptlists, and copying the whole/usr/local/libdirectory to preserve symlinks instead of copying files one by one.