Niklas Vincent

Testing nginx configuration on Travis CI

This blog is merely a reverse proxied version of the Github page nlindblad.github.io, but with an SSL certificate that I control.

The proxying is done using nginx and the nginx configuration gets generated by a Python script using some templates that can be found in the repository itself.

I’ve been using Travis for the past year in order to assure that any configuration changes or updates to content don’t break anything (you can read a full summary of how this blog is set up).

A critical step is making sure that the nginx configuration is valid before deploying it to AWS S3 where it later gets downloaded by the server(s).

TL;DR Check out this finished example on Github

The containers performing the build on Travis use Ubuntu 14.04 Trusty Tahr. Using the official nginx package index for Ubuntu, I found a suitable nginx 1.10.0 package that was compiled against the same libraries as the somewhat outdated stock nginx (1.4.6).

As part of the build, the Ubuntu package is downloaded and extracted using dpkg-deb:

# Download nginx binary, if necessary
mkdir -p ${NGINX_CACHE_DIR}
if [[ ! -f "${NGINX_BINARY}" ]]; then
    DEB_TMP_PATH="/tmp/nginx.deb.$$"
    DEB_TMP_UNPACKED="/tmp/nginx-deb/"
    wget "${NGINX_DEB_URL}" -O "${DEB_TMP_PATH}"
    pushd /tmp
    mkdir -p "${DEB_TMP_UNPACKED}"
    dpkg-deb -R "${DEB_TMP_PATH}" $(basename "${DEB_TMP_UNPACKED}")
    cp "${DEB_TMP_UNPACKED}/usr/sbin/nginx" "${NGINX_BINARY}"
    popd
fi

By adding ${NGINX_CACHE_DIR} to the .travis.yml configuration file:

- directories:
   - nginx-cache

we can be sure that Travis can cache the binary and we don’t have to re-download it on each subsequent build.

In the next phase, we simply call the nginx binary and pipe the output to a temporary log file:

${NGINX_CACHE_DIR}/nginx -t -c "${NGINX_CONFIG}" 2>${NGINX_CONFIG_LOG}

Sadly the return code of nginx is not very heplful sometimes for various configuration errors, so we explicitly base our decision about the outcome on the presence of the string syntax is ok:

if [[ $(cat $NGINX_CONFIG_LOG | egrep "syntax is ok" | wc -l) -eq 1 ]]; then
  echo "Nginx configuration OK!"
  exit 0
else
  echo -e "Nginx configuration invalid:\n"
  cat ${NGINX_CONFIG_LOG}
  exit 1
fi

That’s all! You can see a minimal working example on Github.