Skip to content

Commit fc5d895

Browse files
committed
Provided a way to install third-party modules in a sane manner
1 parent 41156d8 commit fc5d895

File tree

6 files changed

+231
-0
lines changed

6 files changed

+231
-0
lines changed

modules/Dockerfile

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
FROM nginx:mainline as builder
2+
3+
ARG ENABLED_MODULES
4+
5+
RUN set -ex \
6+
&& if [ "$ENABLED_MODULES" = "" ]; then \
7+
echo "No additional modules enabled, exiting"; \
8+
exit 1; \
9+
fi
10+
11+
COPY ./ /modules/
12+
13+
RUN set -ex \
14+
&& apt update \
15+
&& apt install -y --no-install-suggests --no-install-recommends \
16+
patch make wget mercurial devscripts debhelper dpkg-dev \
17+
quilt lsb-release build-essential libxml2-utils xsltproc \
18+
equivs git g++ \
19+
&& hg clone https://hg.nginx.org/pkg-oss/ \
20+
&& cd pkg-oss \
21+
&& mkdir /tmp/packages \
22+
&& for module in $ENABLED_MODULES; do \
23+
echo "Building $module for nginx-$NGINX_VERSION"; \
24+
if [ -d /modules/$module ]; then \
25+
echo "Building $module from user-supplied sources"; \
26+
# check if module sources file is there and not empty
27+
if [ ! -s /modules/$module/source ]; then \
28+
echo "No source file for $module in modules/$module/source, exiting"; \
29+
exit 1; \
30+
fi; \
31+
# some modules require build dependencies
32+
if [ -f /modules/$module/build-deps ]; then \
33+
echo "Installing $module build dependencies"; \
34+
apt update && apt install -y --no-install-suggests --no-install-recommends $(cat /modules/$module/build-deps | xargs); \
35+
fi; \
36+
# if a module has a build dependency that is not in a distro, provide a
37+
# shell script to fetch/build/install those
38+
# note that shared libraries produced as a result of this script will
39+
# not be copied from the builder image to the main one so build static
40+
if [ -x /modules/$module/prebuild ]; then \
41+
echo "Running prebuild script for $module"; \
42+
/modules/$module/prebuild; \
43+
fi; \
44+
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
45+
elif make -C /pkg-oss/debian list | grep -P "^$module\s+\d" > /dev/null; then \
46+
echo "Building $module from pkg-oss sources"; \
47+
cd /pkg-oss/debian; \
48+
make rules-module-$module BASE_VERSION=$NGINX_VERSION; \
49+
mk-build-deps --install --tool="apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes" debuild-module-$module/nginx-$NGINX_VERSION/debian/control; \
50+
make module-$module BASE_VERSION=$NGINX_VERSION; \
51+
find ../../ -maxdepth 1 -mindepth 1 -type f -name "*.deb" -exec mv -v {} /tmp/packages/ \;; \
52+
else \
53+
echo "Don't know how to build $module module, exiting"; \
54+
exit 1; \
55+
fi; \
56+
done
57+
58+
FROM nginx:mainline
59+
ARG ENABLED_MODULES
60+
COPY --from=builder /tmp/packages /tmp/packages
61+
RUN set -ex \
62+
&& apt update \
63+
&& for module in $ENABLED_MODULES; do \
64+
apt install --no-install-suggests --no-install-recommends -y /tmp/packages/nginx-module-${module}_${NGINX_VERSION}*.deb; \
65+
done \
66+
&& rm -rf /tmp/packages \
67+
&& rm -rf /var/lib/apt/lists/

modules/Dockerfile.alpine

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
FROM nginx:mainline-alpine as builder
2+
3+
ARG ENABLED_MODULES
4+
5+
RUN set -ex \
6+
&& if [ "$ENABLED_MODULES" = "" ]; then \
7+
echo "No additional modules enabled, exiting"; \
8+
exit 1; \
9+
fi
10+
11+
COPY ./ /modules/
12+
13+
RUN set -ex \
14+
&& apk update \
15+
&& apk add linux-headers openssl-dev pcre-dev zlib-dev openssl abuild \
16+
musl-dev libxslt libxml2-utils make mercurial gcc unzip git \
17+
xz g++ \
18+
# allow abuild as a root user \
19+
&& printf "#!/bin/sh\\n/usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \
20+
&& chmod +x /usr/local/bin/abuild \
21+
&& hg clone https://hg.nginx.org/pkg-oss/ \
22+
&& cd pkg-oss \
23+
&& mkdir /tmp/packages \
24+
&& for module in $ENABLED_MODULES; do \
25+
echo "Building $module for nginx-$NGINX_VERSION"; \
26+
if [ -d /modules/$module ]; then \
27+
echo "Building $module from user-supplied sources"; \
28+
# check if module sources file is there and not empty
29+
if [ ! -s /modules/$module/source ]; then \
30+
echo "No source file for $module in modules/$module/source, exiting"; \
31+
exit 1; \
32+
fi; \
33+
# some modules require build dependencies
34+
if [ -f /modules/$module/build-deps ]; then \
35+
echo "Installing $module build dependencies"; \
36+
apk update && apk add $(cat /modules/$module/build-deps | xargs); \
37+
fi; \
38+
# if a module has a build dependency that is not in a distro, provide a
39+
# shell script to fetch/build/install those
40+
# note that shared libraries produced as a result of this script will
41+
# not be copied from the builder image to the main one so build static
42+
if [ -x /modules/$module/prebuild ]; then \
43+
echo "Running prebuild script for $module"; \
44+
/modules/$module/prebuild; \
45+
fi; \
46+
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
47+
elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \
48+
echo "Building $module from pkg-oss sources"; \
49+
cd /pkg-oss/alpine; \
50+
make abuild-module-$module BASE_VERSION=$NGINX_VERSION; \
51+
apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \
52+
make module-$module BASE_VERSION=$NGINX_VERSION; \
53+
find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \
54+
else \
55+
echo "Don't know how to build $module module, exiting"; \
56+
exit 1; \
57+
fi; \
58+
done
59+
60+
FROM nginx:mainline-alpine
61+
ARG ENABLED_MODULES
62+
COPY --from=builder /tmp/packages /tmp/packages
63+
RUN set -ex \
64+
&& for module in $ENABLED_MODULES; do \
65+
apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \
66+
done \
67+
&& rm -rf /tmp/packages

modules/README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Adding third-party modules to nginx official image
2+
3+
It's possible to extend a mainline image with third-party modules either from
4+
your own instuctions following a simple filesystem layout/syntax using
5+
`build_module.sh` helper script, or failing back to package sources from
6+
`https://hg.nginx.org/pkg-oss`.
7+
8+
## Usage
9+
10+
```
11+
$ docker build --build-arg ENABLED_MODULES="ndk lua" -t my-nginx-with-lua .
12+
```
13+
This command will attempt to build an image called `my-nginx-with-lua` based on
14+
official nginx docker hub image with two modules: `ndk` and `lua`.
15+
By default, a Debian-based image will be used. If you wish to use Alpine
16+
instead, add `-f Dockerfile.alpine` to the command line.
17+
18+
The build script will look for module build definition files on filesystem
19+
directory under the same name as the module (and resulting package) and if
20+
those are not found will try to look up requested modules in the pkg-oss
21+
repository.
22+
23+
For well-known modules we maintain a set of build sources packages over at
24+
`pkg-oss`, so it's probably a good idea to rely on those instead of providing
25+
your own implementation.
26+
27+
As of the time of writing this README, the following modules and their versions
28+
are available from `pkg-oss` repository:
29+
30+
```
31+
/pkg-oss $ LC_ALL=C make -C debian list-all-modules
32+
make: Entering directory '/pkg-oss/debian'
33+
brotli 1.0.0-1
34+
encrypted-session 0.08-1
35+
geoip 1.19.6-1
36+
geoip2 3.3-1
37+
headers-more 0.33-1
38+
image-filter 1.19.6-1
39+
lua 0.10.19-1
40+
modsecurity 1.0.1-1
41+
ndk 0.3.1-1
42+
njs 0.5.0-1
43+
opentracing 0.10.0-1
44+
passenger 6.0.6-1
45+
perl 1.19.6-1
46+
rtmp 1.2.1-1
47+
set-misc 0.32-1
48+
subs-filter 0.6.4-1
49+
xslt 1.19.6-1
50+
make: Leaving directory '/pkg-oss/debian'
51+
```
52+
53+
If you still want to provide your own instructions for a specific module,
54+
organize the build directory in a following way, e.g. for `echo` module:
55+
56+
```
57+
docker-nginx/modules $ tree echo
58+
echo
59+
├── build-deps
60+
├── prebuild
61+
└── source
62+
63+
0 directories, 3 files
64+
```
65+
66+
The scripts expect one file to always exist for a module you wish to build
67+
manually: `source`. It should contain a link to a zip/tarball source code of a
68+
module you want to build. In `build-deps` you can specify build dependencies
69+
for a module as found in Debian or Alpine repositories. `prebuild` is a shell
70+
script (make it `chmod +x prebuild`!) that will be executed prior to building
71+
the module but after installing the dependencies, so it can be used to install
72+
additional build dependencies if they are not available from Debian or Alpine.
73+
Keep in mind that those dependencies wont be automatically copied to the
74+
resulting image and if you're building a library, build it statically.
75+
76+
Once the build is done in the builder image, the built packages are copied over
77+
to resulting image and installed via apt/apk. The resulting image will be
78+
tagged and can be used the same way as an official docker hub image.
79+
80+
Note that we can not provide any support for those modifications and in no way
81+
guarantee they will work as nice as a build without third-party modules. If
82+
you encounter any issues running your image with the modules enabled, please
83+
reproduce with a vanilla image first.

modules/echo/build-deps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
make gcc

modules/echo/prebuild

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
3+
# if a module has a build dependency that is not in debian/alpine
4+
# use this script to fetch/build/install them
5+
#
6+
# note that shared libraries produced as a result of this script will
7+
# not be copied from the builder image to the resulting one, so you need to
8+
# build them statically
9+
10+
echo "No prebuild stage required - all dependencies are satisfied already!"
11+
12+
exit 0

modules/echo/source

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/openresty/echo-nginx-module/archive/v0.62.tar.gz

0 commit comments

Comments
 (0)