Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/bin/bash
### build nginx/openresty as a static binary with most recent libraries.
### apart from build tools, this script depends on sha256sum, tar, curl.
# features
ENABLE_MAIL="${ENABLE_EMAIL:-true}"
ENABLE_MEDIA="${ENABLE_MEDIA:-true}"
ENABLE_WEBDAV="${ENABLE_WEBDAV:-true}"
# immediately delete downloaded archives
CLEANUP_DOWNLOADS="${CLEANUP_DOWNLOADS:-true}"
# build-parts, locations, versions, checksums
NGINX_OPENRESTY_VERSION="${NGINX_OPENRESTY_VERSION:-1.9.7.3}"
NGINX_OPENRESTY_PATH="openresty-${NGINX_OPENRESTY_VERSION}"
NGINX_OPENRESTY_URL="http://openresty.org/download/${NGINX_OPENRESTY_PATH}.tar.gz"
NGINX_OPENRESTY_SHA256="${NGINX_OPENRESTY_SHA256:-3e4422576d11773a03264021ff7985cd2eeac3382b511ae3052e835210a9a69a}"
PCRE_VERSION="${PCRE_VERSION:-8.38}"
PCRE_PATH="pcre-${PCRE_VERSION}"
PCRE_URL="ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/${PCRE_PATH}.tar.gz"
PCRE_SHA256="${PCRE_SHA256:-9883e419c336c63b0cb5202b09537c140966d585e4d0da66147dc513da13e629}"
OPENSSL_VERSION="${OPENSSL_VERSION:-1.0.2f}"
OPENSSL_PATH="openssl-${OPENSSL_VERSION}"
OPENSSL_URL="https://www.openssl.org/source/${OPENSSL_PATH}.tar.gz"
OPENSSL_SHA256="${OPENSSL_SHA256:-932b4ee4def2b434f85435d9e3e19ca8ba99ce9a065a61524b429a9d5e9b2e9c}"
LIBRESSL_VERSION="${LIBRESSL_VERSION:-2.3.2}"
LIBRESSL_PATH="libressl-${LIBRESSL_VERSION}"
LIBRESSL_URL="http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/${LIBRESSL_PATH}.tar.gz"
LIBRESSL_SHA256="${LIBRESSL_SHA256:-80f45fae4859f161b1980cad846d4217417d0c89006ad29c0ea8c88da564a96a}"
# original Mark Adler zlib version
ZLIB_MA_VERSION="${ZLIB_MA_VERSION:-1.2.8}"
ZLIB_MA_PATH="zlib-${ZLIB_MA_VERSION}"
ZLIB_MA_URL="http://zlib.net/${ZLIB_MA_PATH}.tar.gz"
ZLIB_MA_SHA256="${ZLIB_MA_SHA256:-36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d}"
# cloudflare zlib fork based on zlib 1.2.8
ZLIB_CF_VERSION="${ZLIB_CF_VERSION:-1.2.8-cf-a80420}"
ZLIB_CF_GIT_VERSION="${ZLIB_CF_GIT_VERSION:-a80420c63532c25220a54ea0980667c02303460a}"
ZLIB_CF_PATH="zlib-${ZLIB_CF_GIT_VERSION}"
ZLIB_CF_URL="https://github.com/cloudflare/zlib/archive/${ZLIB_CF_GIT_VERSION}.tar.gz"
ZLIB_CF_SHA256="${ZLIB_CF_GIT_SHA256:-85facae505f831e46ef7c6aee0113e7ceceaf5b84413d5c6c3f4c04a4e7e88a4}"
# something in nginx+libressl does not work
SSL_VARIANT="${SSL_VARIANT:-libressl}"
ZLIB_VARIANT="${ZLIB_VARIANT:-cloudflare}"
# yay, shell
TRUE=0
FALSE=1
DOWNLOAD_ERRORS=()
processPackage() {
local NAME=$1
local URL=$2
local SHA256SUM=$3
FILE_TGZ="${NAME}.tar.gz"
SRC_DIR="${NAME##*/}"
if [ ! -f "${FILE_TGZ}" ]; then
curl --silent --insecure --max-filesize 160000000 --output "${FILE_TGZ}" --location "${URL}"
fi
RAW_HASH=$(<"${FILE_TGZ}" sha256sum --binary)
CHECKSUM=${RAW_HASH:0:64}
if [ "${CHECKSUM}" != "${SHA256SUM}" ]; then
DOWNLOAD_ERRORS+=("${NAME} checksum did not match")
return
fi
tar --extract --gzip --directory="./${SRC_DIR}" --file "${FILE_TGZ}" \
|| DOWNLOAD_ERRORS+=("${NAME} could not be extracted")
if [ "${CLEANUP_DOWNLOADS}" == "true" ]; then
rm "${FILE_TGZ}"
fi
}
download() {
set +u
local LINE="$1"
set -u
if [ -z "${LINE}" ]; then
echo
return ${FALSE}
fi
local NAME="${LINE%%;*}" ; LINE="${LINE#*;}"
local URL="${LINE%%;*}" ; LINE="${LINE#*;}"
local SHA256SUM="${LINE%%;*}"
processPackage "${NAME}" "${URL}" "${SHA256SUM}"
}
if [ "${TRACE}" = "true" ]; then
set -x
fi
set -e -u -o pipefail
BASE_DIR=$(pwd)
export CFLAGS='-msse4.2 -mcrc32 -mpclmul -Os -static -static-libgcc'
CONFIGURE_OPTIONS=(
--with-ld-opt="-static"
--with-cpu-opt=generic64
--with-ipv6
--with-threads
--with-file-aio
)
# default user
CONFIGURE_OPTIONS+=(
--user=nginx
--group=nginx
)
# default paths
CONFIGURE_OPTIONS+=(
--prefix=/usr/local/nginx
--sbin-path=/usr/local/sbin/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/nginx.err
--http-log-path=/var/log/nginx/access.log
--http-client-body-temp-path=/var/lib/nginx/temp.body
--http-proxy-temp-path=/var/lib/nginx/temp.proxy
--http-fastcgi-temp-path=/var/lib/nginx/temp.fastcgi
--http-scgi-temp-path=/var/lib/nginx/temp.scgi
--http-uwsgi-temp-path=/var/lib/nginx/temp.uwsgi
--pid-path=/var/run/nginx/nginx.pid
--lock-path=/var/run/nginx/nginx.lock
)
# basic modules
CONFIGURE_OPTIONS+=(
--with-http_realip_module
--with-http_addition_module
--with-http_sub_module
--with-http_auth_request_module
--with-http_random_index_module
--with-http_secure_link_module
--with-http_degradation_module
--with-http_stub_status_module
)
if [ "${ENABLE_MAIL}" == "true" ]; then
CONFIGURE_OPTIONS+=(
--with-mail
--with-mail_ssl_module
)
fi
if [ "${ENABLE_MEDIA}" == "true" ]; then
CONFIGURE_OPTIONS+=(
--with-http_flv_module
--with-http_mp4_module
)
fi
if [ "${ENABLE_WEBDAV}" == "true" ]; then
CONFIGURE_OPTIONS+=(
--with-http_dav_module
)
fi
download "${NGINX_OPENRESTY_PATH};${NGINX_OPENRESTY_URL};${NGINX_OPENRESTY_SHA256}"
# PCRE library
CONFIGURE_OPTIONS+=(
--with-pcre="${BASE_DIR}/${PCRE_PATH}"
--with-pcre-jit
#--with-pcre-opt=--enable-utf
#--with-pcre-opt=--disable-shared
#--with-pcre-opt=--disable-ebdic
)
download "${PCRE_PATH};${PCRE_SHA256};${PCRE_URL}"
# Lua support (not in nginx, openresty only)
CONFIGURE_OPTIONS+=(
--with-lua51
--with-luajit
)
CONFIGURE_OPTIONS+=(--with-http_ssl_module)
if [ "${SSL_VARIANT}" != "libressl" ]; then
CONFIGURE_OPTIONS+=(
--with-openssl="${BASE_DIR}/${OPENSSL_PATH}"
--with-openssl-opt='no-comp'
--with-openssl-opt='no-deprecated'
--with-openssl-opt='enable-ec_nistp_64_gcc_128'
--with-openssl-opt='no-ssl2'
--with-openssl-opt='no-ssl3'
)
download "${OPENSSL_PATH};${OPENSSL_SHA256};${OPENSSL_URL}"
else
CONFIGURE_OPTIONS+=(
--with-openssl="${BASE_DIR}/${LIBRESSL_PATH}"
)
download "${LIBRESSL_PATH};${LIBRESSL_SHA256};${LIBRESSL_URL}"
fi
CONFIGURE_OPTIONS+=(
--with-http_gunzip_module
--with-http_gzip_static_module
)
if [ "${ZLIB_VARIANT}" != "cloudflare" ]; then
CONFIGURE_OPTIONS+=(
--with-zlib="${BASE_DIR}/${ZLIB_MA_PATH}"
--with-zlib-opt=--static
)
download "${ZLIB_MA_PATH};${ZLIB_MA_SHA256};${ZLIB_MA_URL}"
else
CONFIGURE_OPTIONS+=(
--with-zlib="${BASE_DIR}/${ZLIB_CF_PATH}"
--with-zlib-opt=--static
--with-zlib-opt=--64
)
download "${ZLIB_CF_PATH};${ZLIB_CF_SHA256};${ZLIB_CF_URL}"
cd "${BASE_DIR}/${ZLIB_CF_PATH}"
# has to happen outside of make so CFLAGS are considered...
./configure --static --64 >/dev/null
fi
if [ "${#DOWNLOAD_ERRORS[@]}" != "0" ]; then
echo "Download errors:" >&2
for (( i=0; i < ${#DOWNLOAD_ERRORS[@]}; i++ )); do
echo -e "\t${DOWNLOAD_ERRORS[$i]}" >&2
done
exit -1
fi
cd "${BASE_DIR}/${NGINX_OPENRESTY_PATH}"
./configure ${CONFIGURE_OPTIONS[@]}
make -j8
@arnehormann
Copy link
Author

arnehormann commented Feb 27, 2015

from https://gist.github.com/nlindblad/9709182
and https://gist.github.com/steakknife/8247726

For OpenSSL options:

grep -r '^#if.*OPENSSL_NO' . | grep -o 'OPENSSL_NO_[a-zA-Z0-9_]*' | sort -u | sed 's/OPENSSL_//' | tr '[A-Z_]' '[a-z-]'

@arnehormann
Copy link
Author

arnehormann commented Feb 19, 2016

newest version is work in progress...

@ngrande
Copy link

ngrande commented Aug 5, 2019

replace make -j8 with make -j$(grep -c ^processor /proc/cpuinfo) for more fun. Or simply declate it as make and rely on env variable MAKEFLAGS 🤓

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment