Skip to content
Snippets Groups Projects
Commit fc5d895a authored by Konstantin Pavlov's avatar Konstantin Pavlov
Browse files

Provided a way to install third-party modules in a sane manner

parent 41156d8a
No related branches found
No related tags found
No related merge requests found
FROM nginx:mainline as builder
ARG ENABLED_MODULES
RUN set -ex \
&& if [ "$ENABLED_MODULES" = "" ]; then \
echo "No additional modules enabled, exiting"; \
exit 1; \
fi
COPY ./ /modules/
RUN set -ex \
&& apt update \
&& apt install -y --no-install-suggests --no-install-recommends \
patch make wget mercurial devscripts debhelper dpkg-dev \
quilt lsb-release build-essential libxml2-utils xsltproc \
equivs git g++ \
&& hg clone https://hg.nginx.org/pkg-oss/ \
&& cd pkg-oss \
&& mkdir /tmp/packages \
&& for module in $ENABLED_MODULES; do \
echo "Building $module for nginx-$NGINX_VERSION"; \
if [ -d /modules/$module ]; then \
echo "Building $module from user-supplied sources"; \
# check if module sources file is there and not empty
if [ ! -s /modules/$module/source ]; then \
echo "No source file for $module in modules/$module/source, exiting"; \
exit 1; \
fi; \
# some modules require build dependencies
if [ -f /modules/$module/build-deps ]; then \
echo "Installing $module build dependencies"; \
apt update && apt install -y --no-install-suggests --no-install-recommends $(cat /modules/$module/build-deps | xargs); \
fi; \
# if a module has a build dependency that is not in a distro, provide a
# shell script to fetch/build/install those
# note that shared libraries produced as a result of this script will
# not be copied from the builder image to the main one so build static
if [ -x /modules/$module/prebuild ]; then \
echo "Running prebuild script for $module"; \
/modules/$module/prebuild; \
fi; \
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
elif make -C /pkg-oss/debian list | grep -P "^$module\s+\d" > /dev/null; then \
echo "Building $module from pkg-oss sources"; \
cd /pkg-oss/debian; \
make rules-module-$module BASE_VERSION=$NGINX_VERSION; \
mk-build-deps --install --tool="apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes" debuild-module-$module/nginx-$NGINX_VERSION/debian/control; \
make module-$module BASE_VERSION=$NGINX_VERSION; \
find ../../ -maxdepth 1 -mindepth 1 -type f -name "*.deb" -exec mv -v {} /tmp/packages/ \;; \
else \
echo "Don't know how to build $module module, exiting"; \
exit 1; \
fi; \
done
FROM nginx:mainline
ARG ENABLED_MODULES
COPY --from=builder /tmp/packages /tmp/packages
RUN set -ex \
&& apt update \
&& for module in $ENABLED_MODULES; do \
apt install --no-install-suggests --no-install-recommends -y /tmp/packages/nginx-module-${module}_${NGINX_VERSION}*.deb; \
done \
&& rm -rf /tmp/packages \
&& rm -rf /var/lib/apt/lists/
FROM nginx:mainline-alpine as builder
ARG ENABLED_MODULES
RUN set -ex \
&& if [ "$ENABLED_MODULES" = "" ]; then \
echo "No additional modules enabled, exiting"; \
exit 1; \
fi
COPY ./ /modules/
RUN set -ex \
&& apk update \
&& apk add linux-headers openssl-dev pcre-dev zlib-dev openssl abuild \
musl-dev libxslt libxml2-utils make mercurial gcc unzip git \
xz g++ \
# allow abuild as a root user \
&& printf "#!/bin/sh\\n/usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \
&& chmod +x /usr/local/bin/abuild \
&& hg clone https://hg.nginx.org/pkg-oss/ \
&& cd pkg-oss \
&& mkdir /tmp/packages \
&& for module in $ENABLED_MODULES; do \
echo "Building $module for nginx-$NGINX_VERSION"; \
if [ -d /modules/$module ]; then \
echo "Building $module from user-supplied sources"; \
# check if module sources file is there and not empty
if [ ! -s /modules/$module/source ]; then \
echo "No source file for $module in modules/$module/source, exiting"; \
exit 1; \
fi; \
# some modules require build dependencies
if [ -f /modules/$module/build-deps ]; then \
echo "Installing $module build dependencies"; \
apk update && apk add $(cat /modules/$module/build-deps | xargs); \
fi; \
# if a module has a build dependency that is not in a distro, provide a
# shell script to fetch/build/install those
# note that shared libraries produced as a result of this script will
# not be copied from the builder image to the main one so build static
if [ -x /modules/$module/prebuild ]; then \
echo "Running prebuild script for $module"; \
/modules/$module/prebuild; \
fi; \
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \
echo "Building $module from pkg-oss sources"; \
cd /pkg-oss/alpine; \
make abuild-module-$module BASE_VERSION=$NGINX_VERSION; \
apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \
make module-$module BASE_VERSION=$NGINX_VERSION; \
find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \
else \
echo "Don't know how to build $module module, exiting"; \
exit 1; \
fi; \
done
FROM nginx:mainline-alpine
ARG ENABLED_MODULES
COPY --from=builder /tmp/packages /tmp/packages
RUN set -ex \
&& for module in $ENABLED_MODULES; do \
apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \
done \
&& rm -rf /tmp/packages
# Adding third-party modules to nginx official image
It's possible to extend a mainline image with third-party modules either from
your own instuctions following a simple filesystem layout/syntax using
`build_module.sh` helper script, or failing back to package sources from
`https://hg.nginx.org/pkg-oss`.
## Usage
```
$ docker build --build-arg ENABLED_MODULES="ndk lua" -t my-nginx-with-lua .
```
This command will attempt to build an image called `my-nginx-with-lua` based on
official nginx docker hub image with two modules: `ndk` and `lua`.
By default, a Debian-based image will be used. If you wish to use Alpine
instead, add `-f Dockerfile.alpine` to the command line.
The build script will look for module build definition files on filesystem
directory under the same name as the module (and resulting package) and if
those are not found will try to look up requested modules in the pkg-oss
repository.
For well-known modules we maintain a set of build sources packages over at
`pkg-oss`, so it's probably a good idea to rely on those instead of providing
your own implementation.
As of the time of writing this README, the following modules and their versions
are available from `pkg-oss` repository:
```
/pkg-oss $ LC_ALL=C make -C debian list-all-modules
make: Entering directory '/pkg-oss/debian'
brotli 1.0.0-1
encrypted-session 0.08-1
geoip 1.19.6-1
geoip2 3.3-1
headers-more 0.33-1
image-filter 1.19.6-1
lua 0.10.19-1
modsecurity 1.0.1-1
ndk 0.3.1-1
njs 0.5.0-1
opentracing 0.10.0-1
passenger 6.0.6-1
perl 1.19.6-1
rtmp 1.2.1-1
set-misc 0.32-1
subs-filter 0.6.4-1
xslt 1.19.6-1
make: Leaving directory '/pkg-oss/debian'
```
If you still want to provide your own instructions for a specific module,
organize the build directory in a following way, e.g. for `echo` module:
```
docker-nginx/modules $ tree echo
echo
├── build-deps
├── prebuild
└── source
0 directories, 3 files
```
The scripts expect one file to always exist for a module you wish to build
manually: `source`. It should contain a link to a zip/tarball source code of a
module you want to build. In `build-deps` you can specify build dependencies
for a module as found in Debian or Alpine repositories. `prebuild` is a shell
script (make it `chmod +x prebuild`!) that will be executed prior to building
the module but after installing the dependencies, so it can be used to install
additional build dependencies if they are not available from Debian or Alpine.
Keep in mind that those dependencies wont be automatically copied to the
resulting image and if you're building a library, build it statically.
Once the build is done in the builder image, the built packages are copied over
to resulting image and installed via apt/apk. The resulting image will be
tagged and can be used the same way as an official docker hub image.
Note that we can not provide any support for those modifications and in no way
guarantee they will work as nice as a build without third-party modules. If
you encounter any issues running your image with the modules enabled, please
reproduce with a vanilla image first.
make gcc
#!/bin/sh
# if a module has a build dependency that is not in debian/alpine
# use this script to fetch/build/install them
#
# note that shared libraries produced as a result of this script will
# not be copied from the builder image to the resulting one, so you need to
# build them statically
echo "No prebuild stage required - all dependencies are satisfied already!"
exit 0
https://github.com/openresty/echo-nginx-module/archive/v0.62.tar.gz
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment