DevOps

Сборка nginx из исходников в Docker с multi-stage

Пошаговое руководство по сборке nginx из исходников в Docker с использованием multi-stage build. Настройка стандартных модулей и запуск бинарника во втором образе.

1 ответ 1 просмотр

Как собрать nginx из исходников со стандартными модулями и запустить бинарник во втором Docker образе? Я изучаю DevOps и столкнулся с заданием, где не понимаю процесс сборки бинарника во втором образе. Могли бы вы порекомендовать обучающие материалы или объяснить этот процесс?

Сборка nginx из исходников в Docker-контейнере с multi-stage build — это эффективный способ получить оптимизированный docker nginx образ со стандартными модулями вроде --with-http_ssl_module и --with-http_v2_module. Первый этап builder собирает бинарник из исходников, устанавливая зависимости и настраивая ./configure, а второй runtime-образ копирует готовый nginx бинарник, минимизируя размер. Такой подход идеален для docker build nginx задач в DevOps, где нужен контроль над модулями без лишнего веса.


Содержание


Почему стоит собирать nginx из исходников в Docker

Представьте: стандартный образ nginx:alpine из Docker Hub удобен, но что если вам нужны специфические стандартные модули, как stream для TCP-прокси или gzip_static для сжатия? Официальные образы не всегда включают всё под вашу задачу. А сборка nginx из исходников даёт полный контроль — добавляете флаги ./configure, компилируете под ARM или x86, и вуаля, кастомный docker nginx без мусора.

Почему multi-stage? Первый этап — тяжёлый builder с gcc и библиотеками, где рождается бинарник. Второй — лёгкий runtime, куда копируется только итог. Результат: образ в 10-20 МБ вместо 100+. Это не прихоть, а DevOps-практика для production, где каждый мегабайт на счету. Docker рекомендует такой подход в своей документации по multi-stage, и NGINX тоже не против — их гид по Docker намекает на кастомизацию.

Но подождите, а если вы новичок? Не пугайтесь: процесс линейный, как конвейер. Начнём с основ.


Подготовка: зависимости и исходники nginx

Сначала — база. Выберем Alpine Linux для builder: apk пакеты лёгкие, musl libc вместо glibc. Зависимости для nginx сборки стандартны: компилятор, PCRE, OpenSSL, Zlib. Без них ./configure упадёт с ошибкой “pcre.h: No such file”.

Вот типичный список для apk:

apk add --no-cache \
 build-base \
 pcre-dev \
 openssl-dev \
 zlib-dev \
 linux-headers

Скачайте исходники: wget https://nginx.org/download/nginx-1.26.0.tar.gz (проверьте актуальную версию на nginx.org, на 2026 год это stable). Распакуйте, и вперёд к configure.

А почему именно эти dev-пакеты? PCRE для regex в rewrite, OpenSSL для SSL/TLS, Zlib для gzip. Стандартные модули nginx зависят от них — без openssl-dev не соберётся http_ssl_module. Если забудете linux-headers, make modules скажет “kernel.h not found”. Да, мелочь, но в DevOps такие “мелочи” крадут часы.


Первый этап multi-stage: сборка бинарника

Вот сердце Dockerfile. FROM alpine AS builder. Устанавливаем зависимости, качаем tar.gz, configure с флагами, make && make install. Ключ: --with-compat для динамических модулей, --modules-path для их размещения.

Пример фрагмента (адаптировано из полезного гиста):

dockerfile
FROM alpine:3.19 AS builder

ARG NGINX_VERSION=1.26.0
RUN apk add --no-cache build-base pcre-dev openssl-dev zlib-dev linux-headers curl \
 && curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -xz -C /tmp \
 && cd /tmp/nginx-${NGINX_VERSION} \
 && ./configure \
 --prefix=/etc/nginx \
 --sbin-path=/usr/sbin/nginx \
 --modules-path=/usr/lib/nginx/modules \
 --conf-path=/etc/nginx/nginx.conf \
 --error-log-path=/var/log/nginx/error.log \
 --http-log-path=/var/log/nginx/access.log \
 --pid-path=/var/run/nginx.pid \
 --lock-path=/var/run/nginx.lock \
 --user=nginx \
 --group=nginx \
 --with-compat \
 --with-file-aio \
 --with-threads \
 --with-http_ssl_module \
 --with-http_v2_module \
 --with-http_realip_module \
 --with-http_addition_module \
 --with-http_sub_module \
 --with-http_dav_module \
 --with-http_flv_module \
 --with-http_mp4_module \
 --with-http_gunzip_module \
 --with-http_gzip_static_module \
 --with-http_random_index_module \
 --with-http_secure_link_module \
 --with-http_stub_status_module \
 --with-http_auth_request_module \
 --with-http_xslt_module=dynamic \
 --with-http_image_filter_module=dynamic \
 --with-http_geoip_module=dynamic \
 --with-http_perl_module=dynamic \
 --with-stream \
 --with-stream_realip_module \
 --with-stream_ssl_module \
 --with-stream_ssl_preread_module \
 && make -j$(nproc) \
 && make install

Это собирает бинарник в /usr/sbin/nginx и модули в /usr/lib/nginx/modules. Флаги — из официального списка configure на nginx.org. Динамические (dynamic) позволяют load_module в conf без пересборки.

Проблемы? Если ARM, добавьте --with-cc-opt=“-static”. Очистка: apk del .build-deps && rm -rf /tmp/* — экономит место.


Второй этап: runtime-образ и запуск nginx

Теперь магия COPY --from=builder. FROM чистый alpine, копируем бинарник, модули, создаём пользователя nginx, конфиги. Нет компиляторов — образ лёгкий.

Продолжение Dockerfile:

dockerfile
FROM alpine:3.19
RUN apk add --no-cache pcre openssl zlib ca-certificates \
 && adduser -D -g 'nginx' nginx \
 && mkdir -p /var/log/nginx /var/cache/nginx /var/run/nginx /docker-entrypoint.d \
 && chown -R nginx:nginx /var/cache/nginx /var/log/nginx /var/run/nginx /docker-entrypoint.d

COPY --from=builder /etc/nginx /etc/nginx
COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
COPY --from=builder /usr/lib/nginx/modules/*.so /usr/lib/nginx/modules/

COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80 443
STOPSIGNAL SIGQUIT
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]

Запуск бинарника: CMD запускает его foreground. В nginx.conf добавьте load_module /usr/lib/nginx/modules/ngx_http_xslt_module.so; для динамических.

Почему chown? Nginx не любит root. Без ca-certificates SSL не заработает. Такой runtime-образ — 15-25 МБ, готов к prod.


Настройка стандартных модулей и конфигурации

Стандартные модули — это не только статические. Динамические (–with-http_xslt_module=dynamic) грузятся в conf:

load_module modules/ngx_http_geoip_module.so;
load_module modules/ngx_http_image_filter_module.so;

В server блоке: ssl_protocols TLSv1.2 TLSv1.3; для ssl_module. Upstream для балансировки: upstream backend { server backend1:8080; }.

Из StackOverflow примера видно: NGINX_ARGS=$(nginx -V 2>&1 | sed …) автоматизирует флаги. Тестируйте: docker run -p 80:80 yourimage.

А если модуль не грузится? Проверьте ls /usr/lib/nginx/modules/ и nginx -V.


Сборка образа и запуск: практические команды

Собираем: docker build -t my-nginx .

Проверяем: docker run --rm -it my-nginx nginx -V — увидите модули.

Запуск: docker run -d -p 80:80 -v /path/to/conf:/etc/nginx/conf.d my-nginx

Масштаб: docker-compose с volumes. Для nginx alpine docker — этот подход выигрывает по размеру. Ошибки? “nginx: [emerg] bind() failed” — проверьте порты.

В репо tsuru/docker-nginx-with-modules есть build-arg для модулей — клонируйте и экспериментируйте.


Обучающие материалы и репозитории

Для DevOps-новичка начните с гиста Herman Banken — полный Dockerfile + ошибки. Warlord0 блог объясняет multi-stage на пальцах.

Репозитории:

Практика: соберите, добавьте php-fpm (docker nginx php), deploy в Swarm. YouTube: “nginx docker multi stage” — полно туториалов.


Источники

  1. Gist: Multi-stage NGINX Dockerfile — Полный пример сборки с configure флагами и ошибками: https://gist.github.com/hermanbanken/96f0ff298c162a522ddbba44cad31081/
  2. Docker multi-stage builds — Официальный гид по многоэтапной сборке образов: https://docs.docker.com/build/building/multi-stage/
  3. NGINX Docker installation — Руководство по установке и кастомизации NGINX в Docker: https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/
  4. StackOverflow: NGINX dynamic modules in Docker — Изменения официального образа для misc модулей: https://stackoverflow.com/questions/57739560/what-do-i-need-to-change-in-nginx-official-dockers-image-to-have-the-set-misc-n
  5. tsuru/docker-nginx-with-modules — GitHub репозиторий с build-arg для модулей: https://github.com/tsuru/docker-nginx-with-modules
  6. CodeReview: NGINX Docker from source — Оптимизированный образ с cleanup и permissions: https://codereview.stackexchange.com/questions/283687/nginx-docker-image-with-built-from-source-with-modules
  7. nginx-build-module — Docker-окружение для сборки NGINX модулей: https://github.com/mwhipple/nginx-build-module

Заключение

Сборка nginx из исходников в Docker через multi-stage — ключевой навык для DevOps: builder этап даёт бинарник со стандартными модулями (–with-http_ssl_module и др.), runtime запускает его чисто и быстро. Соберите свой docker build nginx образ по примеру выше, поэкспериментируйте с флагами и репозиториями — и задание решено. Главное: проверяйте nginx -V, оптимизируйте размер, практикуйтесь на реальных сценариях вроде proxy или load balancing. Удачи в изучении!

Авторы
Проверено модерацией
Модерация