For a project I’m working on I needed to be able to rewrite the content of a page as it’s sent back to me from a remote server (via proxy_pass in nginx).
I’ve been using Alpine Linux more as part of very small Docker containers, so I started looking into how nginx is built there. After stumbling around a bit, I found that Alpine uses a ports-like system called aports. I copied the nginx port into a new folder and began working on a Dockerfile.
abuild, the Alpine package build tool seems to be designed to build the whole tree, and the wiki talks about an
abuild build command that apparently does everything except build the package. Sigh. I eventually cobbled enough together from mailing list posts and guesses to figure out that the command I wanted was
abuild -r -fF -c -P /packages
This is where it all went a bit wrong. The module I needed was https://github.com/yaoweibin/ngx_http_substitutions_filter_module, which I added into the APKBUILD script and faked up a sha256sum. abuild doesn’t seem to check this at all, but won’t let the build continue if it’s not listed.
No matter what I did, I got the following failure:
mv: can't rename '/nginx/pkg/nginx/usr/lib/nginx/modules/ngx_http_subs_filter_module.so': No such file or directory >>> ERROR: nginx-mod-http_subs_filter*: _module failed >>> ERROR: nginx*: prepare_subpackages failed >>> ERROR: nginx: all failed
Now, earlier in the build log I could see the module being built, so I couldn’t understand why this was going wrong.
After more stumbling around I found that this was an “old style” module – that couldn’t be built as a dynamic module like the rest of the ones in the script. I wonder why nginx’s build system doesn’t make more noise about this?
A quick patch from https://github.com/yaoweibin/ngx_http_substitutions_filter_module/pull/19 and I had it building as a dynamic module… except that it didn’t. There was still no .so file created, only an intermediate .o somewhere in the tree.
The really strange part of this is that if you try the same thing on a Debian or Ubuntu system, the module will build fine. At this point I’d wasted a lot of time trying to build on Alpine, so I switched my baseimage over to use
nginx-full, which already has the module I need and continued with my project.
It’s not all bad though, I created a couple of good things while trying to get this to work. One is a debug version of
abuild, which was as simple as changing
#!/usr/bin/ash -e to
#!/usr/bin/ash -xe. It’s up on docker as
voltagex/alpine-builder-debug if you really need it. This is helpful if you’re trying to build packages for Alpine and things aren’t working as you expect. Be warned though, this produces a lot of output.
Update: awilfox has a much better patch for abuild that is available at http://foxkit.us/linux/0002-abuild-Add-verbose-option-v-to-show-everything.patch – this adds the traditional -v option to turn on verbose output. It does the same thing as my hack, but is cleaner.