Сборка Nginx в DEB-пакет

Date April 8th, 2014 Author Vitaly Agapov

И тут на Ёжика, шурша и осыпаясь, обрушилась тишина.

Сергей Козлов «Ёжик в тумане»

nginx deb package

Нижеследующий текст не претендует на полноту, объективность и, может быть, даже на полезность. Это просто очередной кусок скомканных заметок, которые я для себя оставляю в Evernote, а потом изредка достаю оттуда, разбавляю бестолковыми комментариями и переношу в бложик в беспочвенной надежде, что кому-нибудь пригодится. В данном случае это будет статья по сборке Nginx из исходников в Debian-пакет для размещения его на своём локальном репозитории. Этот навык полезен в том случае, когда Nginx работает на нескольких машинах и хочется удобно обновлять его сразу везде.

Впрочем, и не обязательно иметь несколько машин. Даже если речь идёт об одном сервере, хорошим тоном будет устанавливать программы через менеджер пакетов. В будущем эта привычка сможет оградить от многих проблем и добавить удобства упраления файлами. В Debian/Ubuntu от make && make install стоит отказаться ради душевного спокойствия и очистки кармы.

Так-то в большинстве случаев можно просто ставить Nginx из официальных репозиториев (или даже с LaunchPad'а, где всегда можно найти распоследнюю версию), но Nginx не умеет подключать внешние модули. Хочешь нестандартный модуль – компилируй. Этим и займёмся.

 

ModSecurity

В моём случае этим нестандартным модулем будет ModSecurity. Про его сборку я уже писал ранее, так что всё кратко:

wget https://www.modsecurity.org/tarball/2.7.7/modsecurity-apache_2.7.7.tar.gz
tar -xzvf modsecurity-apache_2.7.7.tar.gz
cd modsecurity-apache_2.7.7
apt-get install apache2-dev libxml2-dev libcurl4-openssl-dev
./configure --enable-standalone-module
make

Подготовка

Установим нужные для сборки пакеты:

apt-get install devscripts build-essential dpkg-dev debhelper autotools-dev dh-make libgeoip-dev libperl-dev libcap-dev
 
Скачаем исходники:

wget http://nginx.org/download/nginx-1.4.7.tar.gz
tar -xzvf nginx-1.4.7.tar.gz
mv nginx-1.4.7 nginx-my-1.4.7
cd ../nginx-1.4.7/

Особенностью моей истории является то, что я меняю название пакета. То есть хочу, чтобы моя сборка Nginx была в репозитории под названием, скажем, nginx-my и не пересекалась с обычными пакетами nginx-full, nginx-light, nginx-naxsi о прочими. Поэтому я заодно и меняю название папки с исходниками.

Дебианизация

Слово дурацкое, но что поделаешь. Фактически нам тут нужно сделать специальную директорию debian, содержащую набор файлов, определяющих все свойства пакета, включая инструкции для сборщика, changelog и прочее. Вот здесь можно прочитать об основных файлах подробнее.

И тут можно пойти двумя путями: прямым и весьма читерско-окольным.

Первый способ – это создание рыбы всех файлов с помощью команды

dh_make --createorig

Предполагается, что директория имеет вид "имя-версия". А опция –createorig создаёт архивный файл имя-версия.orig.tar.gz. Если такой файл там уже есть, то опция не нужна.
После создания каталога debian файлы в нём нужно под свои цели править вручную.

Второй способ – это использование каталога debian из исходников в репозитории. Для этого надо скачать из репозитория пакет:

apt-get source nginx

и скопировать всю папку debian оттуда. Но её придётся должным образом доработать, так что оба способа потребуют определённых трудозатрат. Я выбрал всё-таки второй.

Итак, что нужно сделать по порядку:

1. Положить ModSecurity в debian/modules:

cp -r modsecurity-apache_2.7.7 nginx-my-1.4.7/debian/modules/

2. Удалить старые патчи:

cd nginx-my-1.4.7/debian/
rm patches/*

3. Поправить файл control. Этот файл содержит общую информацию о пакете, и если за основу взят файл control из репозитория, то его нужно сильно сократить. Мой вариант выглядит так:

01.Source: nginx-my
02.Section: httpd
03.Priority: optional
04.Maintainer: Vitaly Agapov <mymail>
05.Build-Depends: autotools-dev,
06.               debhelper (>= 7),
07.               dpkg-dev (>= 1.15.5),
08.               libexpat-dev,
09.               libgeoip-dev,
10.               libpcre3-dev,
11.               libssl-dev,
12.               po-debconf,
13.               libegl1-mesa,
14.               libgl1-mesa-glx,
15.               zlib1g-dev
16.Standards-Version: 3.9.4
17.Homepage: http://nginx.net
18. 
19.Package: nginx-my
20.Architecture: all
21.Depends: lsb-base (>= 3.2-14), ${misc:Depends}, ${shlibs:Depends}
22.Conflicts: nginx, nginx-common, nginx-full, nginx-light, nginx-naxsi, nginx-extras
23.Description: Nginx with ModSecurity

Для определения списка зависимостей можно воспользоваться утилитой dpkg-depcheck из пакета devscripts:

01.dpkg-depcheck -d ./configure --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin/nginx --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --with-http_geoip_module --with-http_stub_status_module --with-http_ssl_module --with-ipv6 --add-module=debian/modules/modsecurity-apache_2.7.7/nginx/modsecurity/
02. 
03.Packages needed:
04.  srvadmin-omcommon
05.  libpcre3-dev:amd64
06.  libegl1-mesa:amd64
07.  srvadmin-isvc
08.  libgeoip-dev
09.  srvadmin-omacore
10.  srvadmin-storelib
11.  libgl1-mesa-glx:amd64
12.  srvadmin-storage
13.  libssl1.0.0:amd64
14.  srvadmin-realssd
15.  zlib1g-dev:amd64
16.  srvadmin-hapi
17.  libssl-dev:amd64
18.  srvadmin-deng

Эти пакеты и нужно поместить в Build-Depends файла control.

4. Поправить changelog. Тут две главные тонкости. Во-первых, имя пакета в changelog должно совпадать с именем пакета в control и в названии каталога, в котором мы работаем. Во вторых, версия в последней записи будет соответствовать версии пакета, которая получится при сборке.

Поэтому нужно в начало файла changelog дописать секцию вида:

1.nginx-my (1.4.7-build1) saucy; urgency=low
2. 
3.  * Initial release for myrepo.example.com
4. 
5. -- Vitaly Agapov Fri, 04 Apr 2014 15:00:00 +0400

Старый записи можно либо удалить, либо оставить. Чтобы не ошибиться с синтаксисом, можно для добавления секции воспользоваться утилитой dch из того же пакета devscripts:

dch -v 1.4.7-build2

5. Переименовать служебные файлы.

В каталоге debian здесь лежат файлы, необходимые для работы отдельных команд из файла rules. Если имя пакета меняется, то эти файлы нужно переименовать. Например, команда dh_install использует файл packagename.install. Команда dh_installdirs – файл packagename.dirs.

Вот быстрый вариант:

for a in `ls nginx-common*`; do mv $a `echo $a | sed 's/nginx-common/nginx-my/'`; done

Плюс в конец файла nginx-my.install нужно добавить строчку 

debian/build/objs/nginx usr/sbin

Так как сборку мы будем производить в каталог build (и для этого ещё соответствующим образом нужно будет поправить файл rules). Плюс в файл nginx-my.dirs добавить строчку

usr/sbin

6. Поправить дефолтные конфиги.

В файле nginx-my.install указано, что в etc/nginx при инсталляции будут положены файлы из debian/conf/. И это отличная возможность поправить конфиги на более вменяемые. Это уж на своё усмотрение.

Вообще свои грязные ручки тут можно запустить куда угодно. Хоть в конфиг для logrotate, хоть в описание сервиса для SystemD (nginx-my.service).

7. Поправить файл rules.

Это почти обычный Makefile и он при сборке является основным руководством к действию для сборщика. В самом простом случае, когда мы не меняем название пакета и нам наплевать на то, что в репозиторном файле прописана сразу россыпь разных пакетов nginx с разным набором модулей, мы можем просто поправить в нём ключи для скрипта configure и сразу перейти к следующему шагу.

В нашем же случае файл rules можно привести примерно к такому виду:

001.#!/usr/bin/make -f
002. 
003.CFLAGS = `dpkg-buildflags --get CFLAGS`
004.CFLAGS += -Wall -DFORTIFY_SOURCE=2 -fstack-protector
005.CFLAGS += `dpkg-buildflags --get CPPFLAGS`
006.LDFLAGS = `dpkg-buildflags --get LDFLAGS`
007.export CFLAGS LDFLAGS
008. 
009.BUILDDIR = $(CURDIR)/debian/build
010.MODULESDIR = $(CURDIR)/debian/modules
011.BASEDIR = $(CURDIR)
012. 
013.DEB_BUILD_ARCH ?=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
014. 
015.ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
016.    NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
017.    ifeq (${NUMJOBS}, 0)
018.        NUMJOBS = 1
019.    endif
020.else
021.    NUMJOBS = 1
022.endif
023. 
024.config.sub:
025.    dh_testdir
026.ifneq "$(wildcard /usr/share/misc/config.sub)" ""
027.        cp -f /usr/share/misc/config.sub config.sub
028.endif
029. 
030.config.guess:
031.    dh_testdir
032.ifneq "$(wildcard /usr/share/misc/config.guess)" ""
033.        cp -f /usr/share/misc/config.guess config.guess
034.endif
035. 
036.config.env:
037.    dh_testdir
038.    mkdir -p $(BUILDDIR)
039.    cp -Pa $(CURDIR)/auto $(BUILDDIR)/
040.    cp -Pa $(CURDIR)/conf $(BUILDDIR)/
041.    cp -Pa $(CURDIR)/configure $(BUILDDIR)/
042.    cp -Pa $(CURDIR)/contrib $(BUILDDIR)/
043.    cp -Pa $(CURDIR)/src $(BUILDDIR)/
044.    cp -Pa $(CURDIR)/man $(BUILDDIR)/
045. 
046.config.status: config.env config.sub config.guess
047.    cd $(BUILDDIR) && CFLAGS="$(CFLAGS)" CORE_LINK="$(LDFLAGS)" ./configure  \
048.        --prefix=/etc/nginx \
049.        --conf-path=/etc/nginx/nginx.conf \
050.            --sbin-path=/usr/sbin/nginx \
051.        --error-log-path=/var/log/nginx/error.log \
052.        --http-client-body-temp-path=/var/lib/nginx/body \
053.        --http-log-path=/var/log/nginx/access.log \
054.        --http-proxy-temp-path=/var/lib/nginx/proxy \
055.        --lock-path=/var/lock/nginx.lock \
056.        --pid-path=/var/run/nginx.pid \
057.        --without-mail_pop3_module \
058.            --without-mail_imap_module \
059.            --without-mail_smtp_module \
060.            --without-http_fastcgi_module \
061.            --without-http_uwsgi_module \
062.            --without-http_scgi_module \
063.            --without-http_memcached_module \
064.        --with-http_geoip_module \
065.        --with-http_stub_status_module \
066.        --with-http_ssl_module \
067.        --with-ipv6 \
068.        --add-module=$(MODULESDIR)/modsecurity-apache_2.7.7/nginx/modsecurity \
069.            $(CONFIGURE_OPTS) >$@
070.    touch $@
071. 
072.build-arch: config.status
073.    dh_testdir
074.    touch $@
075.    dh_prep
076.    $(MAKE) -j$(NUMJOBS) -C $(BUILDDIR) build
077. 
078.build-dbg: install
079.    dh_testdir
080.    touch $@
081.    dh_strip --package=nginx-my
082. 
083.build-indep:
084. 
085.build: build-indep build-arch
086.    dh_testdir
087.    touch $@
088. 
089.clean:
090.    dh_testdir
091.    dh_testroot
092.    rm -f build-stamp
093.    rm -f config.sub config.guess
094.    dh_clean
095.    rm -rf $(CURDIR)/debian/build
096.mime-types:
097.     
098. 
099.install: mime-types
100.    dh_testdir
101.    dh_testroot
102.    dh_prep
103.    dh_installdirs
104.    dh_install
105. 
106.binary-indep: build install
107.    dh_testdir
108.    dh_testroot
109.    dh_installman -i
110.    dh_installchangelogs -i -k CHANGES
111.    dh_installdocs -i
112.    dh_installdebconf
113.    dh_installexamples -i
114.    dh_installinit -r --no-start -i --name=nginx
115.    cp debian/logrotate debian/nginx-my/etc/logrotate.d/nginx
116.    mkdir -p debian/nginx-my/lib/systemd/system
117.    cp debian/nginx-my.service debian/nginx-my/lib/systemd/system/nginx.service
118.    dh_link -i
119.    dh_compress -i
120.    dh_fixperms -i
121.    dh_installdeb -i
122.    dh_gencontrol -i
123.    dh_md5sums -i
124.    dh_builddeb -i
125. 
126.binary-arch: install build-dbg
127.    dh_testdir
128.    dh_testroot
129.    dh_installchangelogs -a -k CHANGES
130.    dh_installdocs -a
131.    dh_link -aA
132.    dh_compress -a
133.    dh_perl -a
134.    dh_fixperms -a
135.    dh_installdeb -a
136.    dh_shlibdeps -a
137.    dh_gencontrol -a
138.    dh_md5sums -a
139.    dh_builddeb -a
140. 
141.binary: binary-indep binary-arch
142. 
143..PHONY: build clean binary-indep binary-arch binary install

Сборка пакета

dpkg-buildpackage -b -rfakeroot -us -uc

Проект сконфигурируется, скомпилируется и соберётся в DEB-пакет. Дальше останется просто положить пакет в репозиторий. Для этого скопируем файл в папку репозитория, dpkg-scanpackages в руки и вперёд. Но это уже другая история.

Tags: ,
Category: Linux, Nginx | No comments »

Comments

Leave a comment

 Comment Form