#!/bin/sh # ### start ab-nginx container using params file variables # # text formatting presets if command -v tput > /dev/null; then cyan=$(tput bold)$(tput setaf 6) err=$(tput bold)$(tput setaf 1) magenta=$(tput sgr0)$(tput setaf 5) norm=$(tput sgr0) yellow=$(tput sgr0)$(tput setaf 3) width=$(tput cols) else cyan='' err='' magenta='' norm='' yellow='' width=80 fi ### parameter defaults shell=false container_name="ab-nginx" NETWORK='nginx_network' SUBNET='172.31.254.0/24' HTTP_PORT=80 HTTPS_PORT=443 unset CONFIG_DIR unset SERVERS_DIR unset WEBROOT_DIR unset vmount ### functions checkExist () { if [ "$1" = 'file' ]; then if [ ! -f "$2" ]; then printf "${err}\nCannot find file: '$2'. Exiting.\n${norm}" exit 3 fi elif [ "$1" = 'dir' ]; then if [ ! -d "$2" ]; then printf "${err}\nCannot find directory: '$2'. Exiting.\n${norm}" exit 3 fi fi return 0 } scriptHelp () { printf "\n%s%1000s\n" "$magenta" | tr " " "-" | cut -c -$width printf "%s" "$norm" textblock "This is a simple helper script so you can avoid lengthy typing when working with the nginx container. The script reads the contents of 'ab-nginx.params' and constructs various 'docker run' commands based on that file. The biggest time-saver is working with certificates. If they are specified in the params file, the script will automatically bind-mount them so nginx serves content via SSL by default." newline textblock "If you run the script with no parameters, it will execute the container 'normally': Run in detached mode with nginx automatically launched and logging to stdout. If you specified certificates, nginx will serve over SSL by default." newline textblock "Note: Containers (except shell) are always set to restart 'unless-stopped'. You must remove them manually if desired." printf "%s" "$magenta" newline textblock "The script has the following parameters:" textblockParam 'parameter in cyan' 'default in yellow' newline textblockParam '-n|--name' 'ab-nginx' textblock "Change the name of the container. This is cosmetic and does not affect operation in any way." newline textblockParam '-s|--shell' 'off: run in detached mode' textblock "Enter the container using an interactive POSIX shell. This happens after startup operations but *before* nginx is actually started. This is a great way to see configuration changes possibly stopping nginx from starting normally." printf "%s" "$yellow" newline textblock "More information can be found at: https://git.asifbacchus.app/ab-docker/ab-nginx/wiki" printf "%s%1000s\n" "$magenta" | tr " " "-" | cut -c -$width exit 0 } newline () { printf "\n" } textblock () { printf "%s\n" "$1" | fold -w "$width" -s } textblockParam() { if [ -z "$2" ]; then # no default printf "%s%s%s\n" "$cyan" "$1" "$norm" else # default param provided printf "%s%s %s(%s)%s\n" "$cyan" "$1" "$yellow" "$2" "$norm" fi } ### pre-requisite checks # is user root or in the docker group? if [ ! "$( id -u )" -eq 0 ]; then if ! id -Gn | grep docker > /dev/null; then printf "${err}\nYou must either be root or in the 'docker' group to run this script since you must be able to actually start the container! Exiting.\n${norm}" exit 2 fi fi # does the params file exist? checkExist 'file' './ab-nginx.params' # read .params file . ./ab-nginx.params # fix case of TLS13_ONLY var if [ "$TLS13_ONLY" ]; then TLS13_ONLY=$( printf "%s" "$TLS13_ONLY" | tr "[:lower:]" "[:upper:]" ) fi # check for certs if using SSL if [ "$SSL_CERT" ]; then checkExist 'file' "$SSL_CERT"; fi if [ "$SSL_KEY" ]; then checkExist 'file' "$SSL_KEY"; fi if [ "$SSL_CHAIN" ]; then checkExist 'file' "$SSL_CHAIN"; fi # check for DHparam if using TLS1.2 if [ "$TLS13_ONLY" = 'FALSE' ]; then if [ -z "$DH" ]; then printf "${err}\nA DHparam file must be specified when using TLS 1.2. Exiting.${norm}\n" exit 5 else checkExist 'file' "$DH" fi fi # check if specified config directory exists if [ "$CONFIG_DIR" ]; then checkExist 'dir' "$CONFIG_DIR" fi # check if specified server-block directory exists if [ "$SERVERS_DIR" ]; then checkExist 'dir' "$SERVERS_DIR" fi # check if specified webroot directory exists if [ "$WEBROOT_DIR" ]; then checkExist 'dir' "$WEBROOT_DIR" fi # set up volume mounts if [ "$CONFIG_DIR" ]; then vmount="$vmount -v $CONFIG_DIR:/etc/nginx/config" fi if [ "$SERVERS_DIR" ]; then vmount="$vmount -v $SERVERS_DIR:/etc/nginx/sites" fi if [ "$SNIPPETS_DIR" ]; then vmount="$vmount -v $SNIPPETS_DIR:/etc/nginx/snippets" fi if [ "$WEBROOT_DIR" ]; then vmount="$vmount -v $WEBROOT_DIR:/usr/share/nginx/html" fi # trim leading whitespace vmount=${vmount##[[:space:]]} # process startup parameters while [ $# -gt 0 ]; do case "$1" in -h|-\?|--help) # display help scriptHelp exit 0 ;; -s|--shell) # start shell instead of default CMD shell=true ;; -n|--name) # container name if [ -z "$2" ]; then printf "${err}\nNo container name specified. Exiting.\n${norm}" exit 1 fi container_name="$2" shift ;; *) printf "${err}\nUnknown option: %s\n" "$1" printf "Use '--help' for valid options.\n\n${norm}" exit 1 ;; esac shift done # create network if it doesn't already exist docker network inspect ${NETWORK} > /dev/null 2>&1 || \ docker network create \ --attachable \ --driver=bridge \ --subnet=${SUBNET} \ ${NETWORK} # run without TLS if [ -z "$SSL_CERT" ]; then if [ $shell = 'true' ]; then # exec shell printf "${cyan}\nRunning SHELL on %s...${norm}\n" "$container_name" docker run --rm -it --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -p ${HTTP_PORT}:80 \ docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh else # exec normally printf "${cyan}\nRunning NGINX on %s...${norm}\n" "$container_name" docker run -d --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -p ${HTTP_PORT}:80 \ --restart unless-stopped \ docker.asifbacchus.app/nginx/ab-nginx:latest fi # run with TLS1.2 elif [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'FALSE' ]; then if [ $shell = 'true' ]; then # exec shell printf "${cyan}\nRunning SHELL on %s (TLS 1.2)...${norm}\n" "$container_name" docker run --rm -it --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -v "$SSL_CERT":/certs/fullchain.pem:ro \ -v "$SSL_KEY":/certs/privkey.pem:ro \ -v "$SSL_CHAIN":/certs/chain.pem:ro \ -v "$DH":/certs/dhparam.pem:ro \ -p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \ docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh else # exec normally printf "${cyan}\nRunning NGINX on %s (TLS 1.2)...${norm}\n" "$container_name" docker run -d --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -v "$SSL_CERT":/certs/fullchain.pem:ro \ -v "$SSL_KEY":/certs/privkey.pem:ro \ -v "$SSL_CHAIN":/certs/chain.pem:ro \ -v "$DH":/certs/dhparam.pem:ro \ -p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \ --restart unless-stopped \ docker.asifbacchus.app/nginx/ab-nginx:latest fi # run with TLS1.3 elif [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'TRUE' ]; then if [ $shell = 'true' ]; then # exec shell printf "${cyan}\nRunning SHELL on %s (TLS 1.3)...${norm}\n" "$container_name" docker run --rm -it --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -v "$SSL_CERT":/certs/fullchain.pem:ro \ -v "$SSL_KEY":/certs/privkey.pem:ro \ -v "$SSL_CHAIN":/certs/chain.pem:ro \ -p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \ docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh else # exec normally printf "${cyan}\nRunning NGINX on %s (TLS 1.3)...${norm}\n" "$container_name" docker run -d --name ${container_name} \ --env-file ab-nginx.params \ -e SERVER_NAMES="$HOSTNAMES" \ $vmount \ --network=${NETWORK} \ -v "$SSL_CERT":/certs/fullchain.pem:ro \ -v "$SSL_KEY":/certs/privkey.pem:ro \ -v "$SSL_CHAIN":/certs/chain.pem:ro \ -p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \ --restart unless-stopped \ docker.asifbacchus.app/nginx/ab-nginx:latest fi fi ### exit gracefully exit 0