How can I build Apache httpd and nginx with just the required features?

The best available versions of httpd and nginx are not currently available in many distributions. Use these instructions if you don't already have a build of httpd or nginx.

These configure invocations strip out various features that aren't needed, and ensure that features necessary for hosting Python applications and potentially useful for debugging web server issues are enabled.

In order to build httpd, download and unpack

apr and apr-util should be unpacked into httpd-2.4.x/srclib, and renamed to apr and apr-util.

In order to build nginx, download and unpack

httpd

# Omit CC setting for 32-bit Linux
export CC="gcc -m64"
./configure \
    --prefix=$HOME/pyweb-install/httpd \
    --enable-mpms-shared=all \
    --enable-exception-hook \
    --with-mpm=event \
    --with-included-apr \
    --enable-load-all-modules \
    --enable-modules=few \
    --enable-cache \
    --enable-cache-disk \
    --enable-deflate \
    --enable-dumpio \
    --enable-expires \
    --enable-log-debug \
    --enable-log-forensic \
    --enable-proxy \
    --enable-slotmem \
    --enable-slotmem-shm \
    --enable-ssl \
    --enable-unixd \
    --disable-access-compat \
    --disable-authz-user \
    --disable-filter \
    --disable-lbmethod-heartbeat \
    --disable-proxy-ajp \
    --disable-proxy-connect \
    --disable-proxy-express \
    --disable-proxy-ftp
(and make and make install)

Adding mod_proxy_uwsgi

If you want to use the uwsgi protocol with httpd, you'll also need to add in the third-party module mod_uwsgi:

$ wget https://raw.githubusercontent.com/unbit/uwsgi/master/apache2/mod_proxy_uwsgi.c
$ $HOME/pyweb-install/httpd/bin/apxs -ci mod_proxy_uwsgi.c
$ echo "LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so" >> /path/to/httpd/conf/httpd.conf
            

Currently I have undiagnosed httpd child process crashes when I try to use mod_proxy_uwsgi. Stay away from mod_proxy_uwsgi for the time being. (Other protocols are plenty fast, but I look forward to trying this out when I have time to debug.)

nginx

./configure \
    --prefix=$HOME/pyweb-install/nginx \
    --with-ipv6 \
    --with-http_ssl_module \
    --without-http_charset_module \
    --without-http_ssi_module \
    --without-http_geo_module \
    --without-http_map_module \
    --without-http_split_clients_module \
    --without-http_memcached_module \
    --without-http_limit_conn_module \
    --without-http_limit_req_module \
    --without-http_empty_gif_module \
    --without-http_browser_module \
    --with-debug
(and make and make install)

Updating default web server configurations

The configuration snippets I show on the following page override some of the configuration in the default httpd and nginx configuration. To resolve that, I made the following changes to the defaults:

httpd.conf

  • Comment out the original Listen 80 directive.
  • At the very bottom of the file, add Include conf/conf.d/*.conf.
  • Create directory /path/to/httpd/conf/conf.d.
  • Configuration snippets with file extension .conf which are placed in the new conf.d directory will be processed.

nginx.conf

  • Change the original listen 80; directive to something like listen 127.0.0.1:65535;
    Yeah, this is a kludge to keep the instructions simple. Alternatively you can simply remove the default server {}.
  • Right before the end of the http {} section, add include conf.d/*.conf;.
  • Create directory /path/to/nginx/conf/conf.d.
  • Configuration snippets with file extension .conf which are placed in the new conf.d directory will be processed.

Identity/permissions

I'm using daemon for both user and group in all the web server and uWSGI configurations. What that means in effect is that none of the requests are handled by a normal user, and portions of request handling in the web server can touch the same resources as those portions running under uWSGI.

In my nginx.conf I uncommented the existing user directive and set it to user daemon daemon;. An alternative would have been to set the User and Group directives in httpd.conf and the user directive in nginx.conf to some alternative value(s) (and synchronize the settings in the uWSGI .ini files as well.