Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7a6d924d9 | |||
| 16f302c3fd | |||
| a6107f7e25 | |||
| 03e0631964 | |||
| 4d5f3fa809 | |||
| fb81443cba | |||
| 92c0217374 | |||
| 750ad05d06 | |||
| 0db9675bc4 | |||
| dd7ef19d88 | |||
| 810cbd44b7 | |||
| 2b583ad7e0 | |||
| 4a1c1e5153 | |||
| 2b55ae11f4 | |||
| 49fa74159b | |||
| 3548d88b63 | |||
| a1e2911dc0 | |||
| a2b08d5a72 | |||
| 85ff24faaf | |||
| 2e2c93b2b1 | |||
| e208d22664 | |||
| bc2a34ddd8 | |||
| a3c6656764 | |||
| b2582b9bad | |||
| 1ee8b8bf03 | |||
| 8c5bbe8d9c | |||
| 60f79fdd45 | |||
| f1faf3fedf | |||
| 4ded854631 | |||
| 8890e662b0 | |||
| a4cebd5216 | |||
| f6efb86f2a | |||
| e499b7982c | |||
| 1c608859e7 | |||
| 7ea21e2cc4 | |||
| d045d098d9 | |||
| 287830ffe7 |
Generated
+9
-2
@@ -2,11 +2,18 @@
|
||||
<project version="4">
|
||||
<component name="CommitMessageInspectionProfile">
|
||||
<profile version="1.0">
|
||||
<inspection_tool class="BodyLimit" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="BodyLimit" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SubjectBodySeparation" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="SubjectLimit" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
<component name="GitSharedSettings">
|
||||
<option name="FORCE_PUSH_PROHIBITED_PATTERNS">
|
||||
<list>
|
||||
<option value="master main" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
|
||||
+37
-16
@@ -1,10 +1,17 @@
|
||||
FROM nginx:mainline-alpine
|
||||
#
|
||||
# build AB-NGINX container (based on NGINX mainline)
|
||||
#
|
||||
|
||||
# default uid for nginx user
|
||||
ARG NGINX_VERSION=1.21.1
|
||||
FROM nginx:${NGINX_VERSION}-alpine
|
||||
ARG NGINX_VERSION
|
||||
|
||||
# default uid and gid for nginx user
|
||||
ARG UID=8080
|
||||
ARG GID=8080
|
||||
|
||||
# create nginx user
|
||||
RUN addgroup --gid ${UID} www-docker \
|
||||
RUN addgroup --gid ${GID} www-docker \
|
||||
&& adduser \
|
||||
-S \
|
||||
-h /home/www-docker \
|
||||
@@ -15,11 +22,13 @@ RUN addgroup --gid ${UID} www-docker \
|
||||
www-docker
|
||||
|
||||
# add libcap, allow nginx to bind to ports <1024, extract fun error pages & create LetsEncrypt challenge directory outside webroot
|
||||
RUN apk --no-cache add libcap \
|
||||
RUN apk --update --no-cache add \
|
||||
libcap \
|
||||
openssl \
|
||||
&& setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx \
|
||||
&& cd /usr/share/nginx \
|
||||
&& rm -rf html/* \
|
||||
&& wget -O /tmp/errorpages.tar.gz https://git.asifbacchus.app/asif/fun-errorpages/archive/v1.0.tar.gz \
|
||||
&& wget -O /tmp/errorpages.tar.gz https://git.asifbacchus.dev/asif/fun-errorpages/archive/v1.0.tar.gz \
|
||||
&& tar -xzf /tmp/errorpages.tar.gz -C /tmp \
|
||||
&& mv /tmp/fun-errorpages/errorpages ./ \
|
||||
&& rm -rf /tmp/* \
|
||||
@@ -28,22 +37,29 @@ RUN apk --no-cache add libcap \
|
||||
&& mkdir /usr/share/nginx/letsencrypt
|
||||
|
||||
# health check
|
||||
HEALTHCHECK --interval=60s --timeout=5s --start-period=30s --retries=3 \
|
||||
HEALTHCHECK \
|
||||
--interval=10s \
|
||||
--timeout=5s \
|
||||
--start-period=60s \
|
||||
--retries=3 \
|
||||
CMD curl --fail http://127.0.0.1:9000/nginx_status || exit 1
|
||||
|
||||
# standardized labels
|
||||
LABEL author="Asif Bacchus <asif@bacchus.cloud>"
|
||||
MAINTAINER Asif Bacchus <asif@bacchus.cloud>
|
||||
LABEL maintainer="Asif Bacchus <asif@bacchus.cloud>"
|
||||
LABEL dev.asifbacchus.docker.internalName="ab-nginx"
|
||||
LABEL org.opencontainers.image.author="Asif Bacchus <asif@bacchus.cloud>"
|
||||
LABEL org.opencontainers.image.url="https://git.asifbacchus.app/ab-docker/ab-nginx"
|
||||
LABEL org.opencontainers.image.documentation="https://git.asifbacchus.app/ab-docker/ab-nginx/wiki"
|
||||
LABEL org.opencontainers.image.source="https://git.asifbacchus.app/ab-docker/ab-nginx.git"
|
||||
LABEL org.opencontainers.image.url="https://git.asifbacchus.dev/ab-docker/ab-nginx"
|
||||
LABEL org.opencontainers.image.documentation="https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki"
|
||||
LABEL org.opencontainers.image.source="https://git.asifbacchus.dev/ab-docker/ab-nginx.git"
|
||||
LABEL org.opencontainers.image.vendor="NGINX"
|
||||
LABEL org.opencontainers.image.title="ab-nginx"
|
||||
LABEL org.opencontainers.image.description="NGINX-mainline-alpine with more logical file location layout and automatic SSL set up if certificates are provided."
|
||||
|
||||
# copy configuration files
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
# copy configuration files and utility scripts
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
COPY generate-cert.sh /usr/local/bin/generate-cert
|
||||
COPY selfsigned.cnf /etc/selfsigned.cnf
|
||||
COPY config /etc/nginx/
|
||||
COPY sites /etc/nginx/sites/
|
||||
COPY webroot /usr/share/nginx/html/
|
||||
@@ -59,7 +75,9 @@ RUN chown -R www-docker:www-docker /usr/share/nginx \
|
||||
&& find /etc/nginx -type d -exec chmod 750 {} \; \
|
||||
&& find /etc/nginx -type f -exec chmod 640 {} \; \
|
||||
&& chown www-docker:www-docker /var/cache/nginx \
|
||||
&& chown www-docker:www-docker /var/log/nginx
|
||||
&& chown www-docker:www-docker /var/log/nginx \
|
||||
&& chmod 644 /etc/selfsigned.cnf \
|
||||
&& chmod 755 /usr/local/bin/generate-cert /usr/local/bin/entrypoint.sh
|
||||
USER www-docker
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
@@ -73,7 +91,7 @@ ENV HSTS=FALSE
|
||||
ENV TLS13_ONLY=FALSE
|
||||
|
||||
# entrypoint script
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ]
|
||||
|
||||
# run NGINX by default
|
||||
STOPSIGNAL SIGQUIT
|
||||
@@ -81,8 +99,11 @@ CMD [ "nginx", "-g", "daemon off;" ]
|
||||
|
||||
# add build date and version labels
|
||||
ARG BUILD_DATE
|
||||
LABEL org.opencontainers.image.version="1.19.9"
|
||||
LABEL app.asifbacchus.docker.internalVersion="4.0-1.19.9"
|
||||
ARG GIT_COMMIT
|
||||
ARG INTERNAL_VERSION
|
||||
LABEL org.opencontainers.image.revision=${GIT_COMMIT}
|
||||
LABEL org.opencontainers.image.version=${NGINX_VERSION}
|
||||
LABEL dev.asifbacchus.docker.internalVersion=${INTERNAL_VERSION}-${NGINX_VERSION}
|
||||
LABEL org.opencontainers.image.created=${BUILD_DATE}
|
||||
|
||||
#EOF
|
||||
|
||||
+21
-2
@@ -54,8 +54,20 @@ fi
|
||||
if [ -f "/certs/fullchain.pem" ]; then
|
||||
# activate SSL configuration as appropriate and only if certs exist
|
||||
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||
if [ -f "/certs/fullchain.pem" ] && [ -f "/certs/privkey.pem" ] && [ -f "/certs/chain.pem" ] && [ -f "/certs/dhparam.pem" ]; then
|
||||
if [ -f "/certs/fullchain.pem" ] && [ -f "/certs/privkey.pem" ] && [ -f "/certs/chain.pem" ]; then
|
||||
printf "Certificates found. Securing deployment using TLS 1.2\n"
|
||||
|
||||
# check for dhparam file and generate, if necessary
|
||||
if ! [ -f "/certs/dhparam.pem" ]; then
|
||||
printf "Diffie-Hellman Parameters not found... generating (using Digital Signature Algorithm instead of Diffie-Hellman)...\n"
|
||||
if ! openssl dhparam -dsaparam -out /certs/dhparam.pem 4096; then
|
||||
printf "\n\nUnable to generate 'dhparam.pem'. Is your '/certs' directory writable by this container?\n"
|
||||
printf "TLS version 1.2 requires DHParams (or DSAParams) in order to function securely. Exiting.\n\n"
|
||||
exit 101
|
||||
fi
|
||||
printf "\nDSA-Params generated successfully\n"
|
||||
fi
|
||||
|
||||
# activate shared SSL configuration file
|
||||
if [ -f "/etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled" ]; then
|
||||
mv /etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled \
|
||||
@@ -123,4 +135,11 @@ fi
|
||||
printf "\nSetup complete...Container ready...\n"
|
||||
exec "$@"
|
||||
|
||||
#EOF
|
||||
|
||||
# exit return codes
|
||||
# 10x certificate generation errors
|
||||
# 101 unable to generate DSA-parameters
|
||||
# 102 unable to generate private key
|
||||
# 103 unable to generate self-signed certificate
|
||||
|
||||
#EOF
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# generate a self-signed certificate
|
||||
#
|
||||
|
||||
# check for null hostname
|
||||
if [ -z "$1" ]; then
|
||||
printf "\nPlease supply a hostname for the generated certificate as a parameter to this script. Exiting.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# update openssl configuration file
|
||||
sed -e "s/{CERT_HOSTNAME}/$1/" /etc/selfsigned.cnf > /tmp/selfsigned.cnf
|
||||
|
||||
printf "\nGenerating self-signed certificate for '%s':\n" "$1"
|
||||
|
||||
# create placeholder files to set permissions
|
||||
if ! touch /certs/fullchain.pem && chmod 644 /certs/fullchain.pem; then
|
||||
printf "\nUnable to write to '/certs', is it mounted writable by this container?\n\n"
|
||||
exit 2
|
||||
fi
|
||||
touch /certs/privkey.pem && chmod 640 /certs/privkey.pem
|
||||
|
||||
# generate certificate
|
||||
if ! openssl req -new -x509 -days 365 -nodes -out /certs/fullchain.pem -keyout /certs/privkey.pem -config /tmp/selfsigned.cnf; then
|
||||
printf "\nUnable to generate certificate. Is the '/certs' directory writable by this container?\n\n"
|
||||
exit 3
|
||||
fi
|
||||
\cp /certs/fullchain.pem /certs/chain.pem
|
||||
|
||||
# print user notification
|
||||
printf "\n\nA self-signed certificate has been generated and saved in the location mounted to '/certs' in this container.\n"
|
||||
printf "The certificate and private key are PEM formatted with names 'fullchain.pem' and 'privkey.pem', respectively.\n"
|
||||
printf "Remember to import 'fullchain.pem' to the trusted store on any client machines or you will get warnings.\n\n"
|
||||
|
||||
# exit gracefully
|
||||
exit 0
|
||||
|
||||
|
||||
#
|
||||
# exit codes
|
||||
# 0: normal exit, no errors
|
||||
# 1: invalid or missing parameters
|
||||
# 2: unable to write to certs directory
|
||||
# 3: unable to generate certificate
|
||||
|
||||
#EOF
|
||||
@@ -0,0 +1,16 @@
|
||||
default_bits = 4096
|
||||
default_md = sha256
|
||||
distinguished_name = dn
|
||||
req_extensions = san
|
||||
x509_extensions = san
|
||||
prompt = no
|
||||
|
||||
[dn]
|
||||
organizationName = AB-NGINX Webserver
|
||||
CN = {CERT_HOSTNAME}
|
||||
|
||||
[san]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = {CERT_HOSTNAME}
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# generate checksums from provided path suitable for use by 'update.sh'
|
||||
#
|
||||
|
||||
# check for missing path to helper files, otherwise strip trailing slash
|
||||
if [ -z "$1" ]; then
|
||||
printf "\nPlease supply path to helper files. Exiting.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
srcDir="${1%/}"
|
||||
|
||||
# verify path exists and is accessible
|
||||
if ! [ -d "$srcDir" ]; then
|
||||
printf "\nUnable to find or read supplied path to helper files. Exiting.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# generate checksum file
|
||||
\rm -f "${srcDir}/checksums.sha256"
|
||||
find "${srcDir}/" -type f -exec sha256sum {} + >>"${srcDir}/checksums.sha256"
|
||||
sed -i "s+$srcDir/++g" "${srcDir}/checksums.sha256"
|
||||
|
||||
# exit gracefully
|
||||
exit 0
|
||||
|
||||
#EOF
|
||||
@@ -6,6 +6,23 @@
|
||||
###
|
||||
|
||||
|
||||
#
|
||||
# Container options
|
||||
#
|
||||
|
||||
# Specify a particular tag to 'version pin' the ab-nginx container.
|
||||
TAG=latest
|
||||
|
||||
# Specify a runtime UID and GID for the container user. This is useful to
|
||||
# ensure the container can read and/or write to locations on the host or
|
||||
# has access to files shared between members of a container stack.
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: NGINX_UID=8080, NGINX_GID=8080
|
||||
# VALID OPTIONS: any permissible and available UID/GID value
|
||||
NGINX_UID=8080
|
||||
NGINX_GID=8080
|
||||
|
||||
|
||||
#
|
||||
# Network options
|
||||
#
|
||||
@@ -16,7 +33,7 @@
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: nginx_network
|
||||
# VALID OPTIONS: network names acceptable to the docker engine
|
||||
#NETWORK=nginx_network
|
||||
NETWORK=nginx_network
|
||||
|
||||
# If you want to specify a particular IP subnet for the network to be created
|
||||
# as per the above variable, specify it here. Again, if you don't know what
|
||||
@@ -24,7 +41,7 @@
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: '172.31.254.0/24'
|
||||
# VALID OPTIONS: subnet in CIDR format
|
||||
#SUBNET='172.31.254.0/24'
|
||||
SUBNET='172.31.254.0/24'
|
||||
|
||||
|
||||
#
|
||||
@@ -38,7 +55,7 @@
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: Etc/UTC
|
||||
# VALID OPTIONS: IANA time zones in TZ format
|
||||
#TZ=Etc/UTC
|
||||
TZ=Etc/UTC
|
||||
|
||||
|
||||
#
|
||||
@@ -55,7 +72,8 @@
|
||||
#
|
||||
# REQUIRED: YES, if using SSL and default server-blocks
|
||||
# DEFAULT: "_"
|
||||
#HOSTNAMES="domain.tld www.domain.tld server.domain.tld alt.domain.tld"
|
||||
# EXAMPLE: HOSTNAMES="domain.tld www.domain.tld server.domain.tld alt.domain.tld"
|
||||
HOSTNAMES="_"
|
||||
|
||||
# Ports to listen on:
|
||||
# If you need to use ports other than HTTP=80 and HTTPS=443, remember to set up
|
||||
@@ -65,8 +83,8 @@
|
||||
# you use here.
|
||||
# REQUIRED: NO
|
||||
# DEFAULTS: 80 and 443, respectively
|
||||
#HTTP_PORT=80
|
||||
#HTTPS_PORT=443
|
||||
HTTP_PORT=80
|
||||
HTTPS_PORT=443
|
||||
|
||||
# Access logging (global preference):
|
||||
# Unless overridden in a server/location block, access logging will be handled
|
||||
@@ -74,7 +92,7 @@
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: OFF
|
||||
# VALID OPTIONS: 'ON' or 'OFF'
|
||||
#ACCESS_LOG=OFF
|
||||
ACCESS_LOG=OFF
|
||||
|
||||
|
||||
#
|
||||
@@ -89,7 +107,7 @@
|
||||
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
||||
# file, simply change its extension (i.e. '.conf.disabled').
|
||||
#
|
||||
# REMEMBER: Your configuration files must be readable by UID 8080!
|
||||
# REMEMBER: Your configuration files must be readable by the container UID/GID!
|
||||
CONFIG_DIR=$(pwd)/config
|
||||
|
||||
# Specify a directory containing your NGINX server-block configurations (if any)
|
||||
@@ -103,7 +121,7 @@ CONFIG_DIR=$(pwd)/config
|
||||
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
||||
# file, simply change its extension (i.e. '.conf.disabled').
|
||||
#
|
||||
# REMEMBER: Your server-block files must be readable by UID 8080!
|
||||
# REMEMBER: Your server-block files must be readable by the container UID/GID!
|
||||
SERVERS_DIR=$(pwd)/sites
|
||||
|
||||
# Specify a directory containing 'snippets' of NGINX code you want/need to
|
||||
@@ -114,11 +132,11 @@ SERVERS_DIR=$(pwd)/sites
|
||||
# instead of having to type the same thing many times.
|
||||
|
||||
# This is totally optional! Comment this variable to disable it.
|
||||
# REMEMBER: Your snippets must be readable by UID 8080!
|
||||
# REMEMBER: Your snippets must be readable by the container UID/GID!
|
||||
SNIPPETS_DIR=$(pwd)/snippets
|
||||
|
||||
# Specify a directory with the content you want to serve.
|
||||
# REMEMBER: This directory must be readable by UID 8080!
|
||||
# REMEMBER: This directory must be readable by the container UID/GID!
|
||||
WEBROOT_DIR=/var/www
|
||||
|
||||
|
||||
@@ -131,26 +149,27 @@ WEBROOT_DIR=/var/www
|
||||
# REQUIRED: NO
|
||||
# DEFAULT: FALSE
|
||||
# VALID OPTIONS: 'TRUE', 'FALSE'
|
||||
#HSTS=FALSE
|
||||
HSTS=FALSE
|
||||
|
||||
# TLS 1.3 mode:
|
||||
# If 'FALSE' (default), NGINX will accept both TLS 1.2 and 1.3 connections.
|
||||
# If 'TRUE', only TLS 1.3 connections will be accepted.
|
||||
#TLS13_ONLY=FALSE
|
||||
TLS13_ONLY=FALSE
|
||||
|
||||
|
||||
#
|
||||
# Certificate files
|
||||
#
|
||||
# If you are mounting symlinks you MUST specify the full path of the symlink so
|
||||
# the target is resolved! DH (Diffie-Hellman Parameters file) is only required
|
||||
# if using TLS 1.2.
|
||||
# the target is resolved!
|
||||
#
|
||||
# REMEMBER: ALL files must be readble by UID 8080!
|
||||
#SSL_CERT=/path/to/your/ssl-certificate/fullchain.pem
|
||||
#SSL_KEY=/path/to/your/ssl-private-key/privkey.pem
|
||||
#SSL_CHAIN=/path/to/your/ssl-certificate-chain/chain.pem
|
||||
#DH=/path/to/your/diffie-hellman-parameters-file/dhparam.pem
|
||||
# REMEMBER: ALL files must be readable by container UID/GID!
|
||||
# EXAMPLES:
|
||||
# SSL_CERT=/path/to/your/ssl-certificate/fullchain.pem
|
||||
# SSL_KEY=/path/to/your/ssl-private-key/privkey.pem
|
||||
# SSL_CHAIN=/path/to/your/ssl-certificate-chain/chain.pem
|
||||
SSL_CERT=""
|
||||
SSL_KEY=""
|
||||
SSL_CHAIN=""
|
||||
|
||||
|
||||
#EOF
|
||||
#EOF
|
||||
|
||||
+288
-212
@@ -4,120 +4,239 @@
|
||||
# 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)
|
||||
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
|
||||
cyan=''
|
||||
err=''
|
||||
magenta=''
|
||||
norm=''
|
||||
yellow=''
|
||||
width=80
|
||||
fi
|
||||
|
||||
### parameter defaults
|
||||
shell=false
|
||||
#
|
||||
# parameter defaults
|
||||
doShell=false
|
||||
doStatus=false
|
||||
doStop=false
|
||||
removeStopped=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
|
||||
CONFIG_DIR=""
|
||||
SERVERS_DIR=""
|
||||
WEBROOT_DIR=""
|
||||
volumeMounts=""
|
||||
stopErr=0
|
||||
removeErr=0
|
||||
|
||||
#
|
||||
# functions
|
||||
checkExist() {
|
||||
if [ "$1" = 'file' ]; then
|
||||
if [ ! -f "$2" ]; then
|
||||
printf "%s\nCannot find file: '$2'. Exiting.\n%s" "$err" "$norm"
|
||||
exit 3
|
||||
if [ "$1" = 'file' ]; then
|
||||
if [ ! -f "$2" ]; then
|
||||
printf "%s\nCannot find file: '$2'. Exiting.\n%s" "$err" "$norm"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$1" = 'dir' ]; then
|
||||
if [ ! -d "$2" ]; then
|
||||
printf "%s\nCannot find directory: '$2'. Exiting.\n$%s" "$err" "$norm"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
elif [ "$1" = 'dir' ]; then
|
||||
if [ ! -d "$2" ]; then
|
||||
printf "%s\nCannot find directory: '$2'. Exiting.\n$%s" "$err" "$norm"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
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 typing lengthy commands when working with the ab-nginx container."
|
||||
textblock "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. If you specified certificates, nginx will serve over SSL by default."
|
||||
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 (optional) 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
|
||||
# header and description
|
||||
printf "\n%s" "$magenta"
|
||||
printf '%.0s-' $(seq "$width")
|
||||
printf "\n%s" "$norm"
|
||||
textBlock "This is a simple helper script so you can avoid typing lengthy commands when working with the ab-nginx container."
|
||||
textBlock "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
|
||||
|
||||
# explanatory text
|
||||
textBlock "If you run the script with no parameters, it will execute the container 'normally': Run in detached mode with nginx automatically launched. If you specified certificates, nginx will serve over SSL by default."
|
||||
textBlock "Note: Containers (except shell) are always set to restart 'unless-stopped'. You must remove them manually if desired."
|
||||
printf "%s" "$magenta"
|
||||
newline
|
||||
|
||||
# parameters
|
||||
textBlock "The script has the following (optional) parameters:"
|
||||
textBlockParam 'parameter in cyan' 'default in yellow'
|
||||
newline
|
||||
textBlockParam '-n|--name' 'ab-nginx'
|
||||
textBlock "Set the name of the container, otherwise the default will be used."
|
||||
newline
|
||||
textBlockParam '-s|--shell' 'off: run in detached mode'
|
||||
textBlock "Enter the container using an interactive ASH/BusyBox 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."
|
||||
newline
|
||||
textBlockParam '--status'
|
||||
textBlock "Run a search for all AB-NGINX containers and display their name and status."
|
||||
newline
|
||||
textBlockParam '--stop'
|
||||
textBlock "Stops the container specified by the '--name' parameter or with the default name 'ab-nginx'."
|
||||
newline
|
||||
textBlockParam '--remove | --stop-remove'
|
||||
textBlock "Stops and removes the container specified by the '--name' parameter or with the default name 'ab-nginx'."
|
||||
|
||||
# footer
|
||||
newline
|
||||
printf "%s" "$yellow"
|
||||
textBlock"More information can be found at: https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki"
|
||||
printf "\n%s" "$magenta"
|
||||
printf '%.0s-' $(seq "$width")
|
||||
printf "\n%s" "$norm"
|
||||
exit 0
|
||||
}
|
||||
|
||||
newline() {
|
||||
printf "\n"
|
||||
printf "\n"
|
||||
}
|
||||
|
||||
textblock() {
|
||||
printf "%s\n" "$1" | fold -w "$width" -s
|
||||
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
|
||||
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
|
||||
#
|
||||
# pre-requisite checks
|
||||
|
||||
# is docker installed?
|
||||
if ! command -v docker > /dev/null; then
|
||||
printf "%s\nCannot find docker... is it installed?\n%s" "$err" "$norm"
|
||||
exit 2
|
||||
if ! command -v docker >/dev/null; then
|
||||
printf "%s\nCannot find docker... is it installed?\n%s" "$err" "$norm"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# is user root or in the docker group?
|
||||
if [ ! "$(id -u)" -eq 0 ]; then
|
||||
if ! id -Gn | grep docker >/dev/null; then
|
||||
printf "%s\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$%s" "$err" "$norm"
|
||||
exit 2
|
||||
fi
|
||||
if ! id -Gn | grep docker >/dev/null; then
|
||||
printf "%s\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$%s" "$err" "$norm"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# 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
|
||||
doShell=true
|
||||
;;
|
||||
-n | --name)
|
||||
# container name
|
||||
if [ -z "$2" ]; then
|
||||
printf "%s\nNo container name specified. Exiting.\n%s" "$err" "$norm"
|
||||
exit 1
|
||||
fi
|
||||
container_name="$2"
|
||||
shift
|
||||
;;
|
||||
--status)
|
||||
# find containers and check their status
|
||||
doStatus=true
|
||||
;;
|
||||
--stop)
|
||||
# stop named container
|
||||
doStop=true
|
||||
;;
|
||||
--remove | --stop-remove)
|
||||
# stop and remove named container
|
||||
doStop=true
|
||||
removeStopped=true
|
||||
;;
|
||||
*)
|
||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||
printf "Use '--help' for valid options.\n\n%s" "$norm"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
#
|
||||
# status check
|
||||
if [ "$doStatus" = "true" ]; then
|
||||
printf "\nFound the following AB-NGINX containers:\n"
|
||||
docker ps -a --filter "label=dev.asifbacchus.docker.internalName=ab-nginx"
|
||||
printf "\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#
|
||||
# stop container
|
||||
if [ "$doStop" = "true" ]; then
|
||||
printf "\nStopping container '%s'... " "$container_name"
|
||||
|
||||
# ensure container exists
|
||||
if ! docker inspect "$container_name" >/dev/null 2>&1; then
|
||||
printf "[ERROR]: No container with that name found.\n\n"
|
||||
exit 11
|
||||
fi
|
||||
|
||||
# stop and/or remove container
|
||||
if ! docker stop "$container_name" >/dev/null 2>&1; then stopErr=1; fi
|
||||
if [ "$removeStopped" = "true" ] && [ "$stopErr" -eq 0 ]; then
|
||||
if ! docker rm "$container_name" >/dev/null 2>&1; then removeErr=1; fi
|
||||
fi
|
||||
|
||||
# update status message
|
||||
if [ "$stopErr" -eq 1 ]; then
|
||||
printf "[ERROR]: Unable to stop container. Please try removing it manually.\n\n"
|
||||
exit 12
|
||||
fi
|
||||
if [ "$removeErr" -eq 1 ]; then
|
||||
printf "[STOPPED]\n"
|
||||
printf "[ERROR]: Unable to remove container. Please try removing it manually.\n\n"
|
||||
exit 13
|
||||
fi
|
||||
if [ "$removeStopped" = "true" ]; then
|
||||
printf "[REMOVED]\n\n"
|
||||
else
|
||||
printf "[STOPPED]\n\n"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#
|
||||
# run container
|
||||
|
||||
# does the params file exist?
|
||||
checkExist 'file' './ab-nginx.params'
|
||||
|
||||
# read .params file
|
||||
# shellcheck source=ab-nginx.params.template
|
||||
. "./ab-nginx.params"
|
||||
|
||||
# fix case of TLS13_ONLY var
|
||||
if [ "$TLS13_ONLY" ]; then
|
||||
TLS13_ONLY=$(printf "%s" "$TLS13_ONLY" | tr "[:lower:]" "[:upper:]")
|
||||
TLS13_ONLY=$(printf "%s" "$TLS13_ONLY" | tr "[:lower:]" "[:upper:]")
|
||||
fi
|
||||
|
||||
# check for certs if using SSL
|
||||
@@ -125,175 +244,132 @@ 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 [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||
if [ -z "$DH" ]; then
|
||||
printf "%s\nA DHparam file must be specified when using TLS 1.2. Exiting.%s\n" "$err" "$norm"
|
||||
exit 5
|
||||
else
|
||||
checkExist 'file' "$DH"
|
||||
fi
|
||||
fi
|
||||
|
||||
# check if specified config directory exists
|
||||
if [ "$CONFIG_DIR" ]; then
|
||||
checkExist 'dir' "$CONFIG_DIR"
|
||||
checkExist 'dir' "$CONFIG_DIR"
|
||||
fi
|
||||
|
||||
# check if specified server-block directory exists
|
||||
if [ "$SERVERS_DIR" ]; then
|
||||
checkExist 'dir' "$SERVERS_DIR"
|
||||
checkExist 'dir' "$SERVERS_DIR"
|
||||
fi
|
||||
|
||||
# check if specified webroot directory exists
|
||||
if [ "$WEBROOT_DIR" ]; then
|
||||
checkExist 'dir' "$WEBROOT_DIR"
|
||||
checkExist 'dir' "$WEBROOT_DIR"
|
||||
fi
|
||||
|
||||
# set up volume mounts
|
||||
if [ "$CONFIG_DIR" ]; then
|
||||
vmount="$vmount -v $CONFIG_DIR:/etc/nginx/config"
|
||||
volumeMounts="${volumeMounts} -v $CONFIG_DIR:/etc/nginx/config"
|
||||
fi
|
||||
if [ "$SERVERS_DIR" ]; then
|
||||
vmount="$vmount -v $SERVERS_DIR:/etc/nginx/sites"
|
||||
volumeMounts="${volumeMounts} -v $SERVERS_DIR:/etc/nginx/sites"
|
||||
fi
|
||||
if [ "$SNIPPETS_DIR" ]; then
|
||||
vmount="$vmount -v $SNIPPETS_DIR:/etc/nginx/snippets"
|
||||
volumeMounts="${volumeMounts} -v $SNIPPETS_DIR:/etc/nginx/snippets"
|
||||
fi
|
||||
if [ "$WEBROOT_DIR" ]; then
|
||||
vmount="$vmount -v $WEBROOT_DIR:/usr/share/nginx/html"
|
||||
volumeMounts="${volumeMounts} -v $WEBROOT_DIR:/usr/share/nginx/html"
|
||||
fi
|
||||
# trim leading whitespace
|
||||
vmount=${vmount##[[:space:]]}
|
||||
volumeMounts=${volumeMounts##[[:space:]]}
|
||||
|
||||
# handle null HOSTNAMES
|
||||
if [ -z "$HOSTNAMES" ]; then HOSTNAMES="_"; fi
|
||||
|
||||
# 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 "%s\nNo container name specified. Exiting.\n%s" "$err" "$norm"
|
||||
exit 1
|
||||
fi
|
||||
container_name="$2"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||
printf "Use '--help' for valid options.\n\n%s" "$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}
|
||||
docker network create \
|
||||
--attachable \
|
||||
--driver=bridge \
|
||||
--subnet=${SUBNET} \
|
||||
${NETWORK}
|
||||
|
||||
# run without TLS
|
||||
if [ -z "$SSL_CERT" ]; then
|
||||
if [ $shell = 'true' ]; then
|
||||
# exec shell
|
||||
printf "%s\nRunning SHELL on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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 "%s\nRunning NGINX on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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 "%s\nRunning SHELL on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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 "%s\nRunning NGINX on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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 "%s\nRunning SHELL on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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 "%s\nRunning NGINX on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
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
|
||||
if [ "$doShell" = 'true' ]; then
|
||||
# exec shell
|
||||
printf "%s\nRunning SHELL on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||
# shellcheck disable=SC2086
|
||||
docker run --rm -it --name "${container_name}" \
|
||||
--env-file ab-nginx.params \
|
||||
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||
-e SERVER_NAMES="$HOSTNAMES" \
|
||||
${volumeMounts} \
|
||||
--network=${NETWORK} \
|
||||
-p ${HTTP_PORT}:80 \
|
||||
docker.asifbacchus.dev/nginx/ab-nginx:latest /bin/sh
|
||||
else
|
||||
# exec normally
|
||||
printf "%s\nRunning NGINX on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||
# shellcheck disable=SC2086
|
||||
docker run -d --name "${container_name}" \
|
||||
--env-file ab-nginx.params \
|
||||
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||
-e SERVER_NAMES="$HOSTNAMES" \
|
||||
${volumeMounts} \
|
||||
--network=${NETWORK} \
|
||||
-p ${HTTP_PORT}:80 \
|
||||
--restart unless-stopped \
|
||||
docker.asifbacchus.dev/nginx/ab-nginx:${TAG:-latest}
|
||||
fi
|
||||
# run with TLS
|
||||
else
|
||||
if [ "$doShell" = 'true' ]; then
|
||||
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||
printf "%s\nRunning SHELL on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
else
|
||||
printf "%s\nRunning SHELL on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
docker run --rm -it --name "${container_name}" \
|
||||
--env-file ab-nginx.params \
|
||||
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||
-e SERVER_NAMES="$HOSTNAMES" \
|
||||
${volumeMounts} \
|
||||
--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.dev/nginx/ab-nginx:${TAG:-latest} /bin/sh
|
||||
else
|
||||
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||
printf "%s\nRunning NGINX on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
else
|
||||
printf "%s\nRunning NGINX on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
docker run -d --name "${container_name}" \
|
||||
--env-file ab-nginx.params \
|
||||
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||
-e SERVER_NAMES="$HOSTNAMES" \
|
||||
${volumeMounts} \
|
||||
--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.dev/nginx/ab-nginx:${TAG:-latest}
|
||||
fi
|
||||
fi
|
||||
|
||||
### exit gracefully
|
||||
exit 0
|
||||
#
|
||||
# exit with code from docker
|
||||
exit "$?"
|
||||
|
||||
#
|
||||
# exit return codes
|
||||
# 0: normal exit, no errors
|
||||
# 1: missing or invalid parameter
|
||||
# 2: cannot find docker
|
||||
# 3: incorrect permissions to access docker
|
||||
# 1x: operation errors
|
||||
# 11 no container found with specified name
|
||||
# 12 unable to stop container
|
||||
# 13 unable to remove container
|
||||
# other refer to docker exit codes
|
||||
|
||||
#EOF
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
- Place all your server block configuration files in this directory
|
||||
- This path should be bind-mounted to the container at:
|
||||
'/etc/nginx/sites'
|
||||
- this bind-mount will override the test pages included in the container by
|
||||
default.
|
||||
- this bind-mount will override the default server configurations
|
||||
included in the container by default.
|
||||
- All files should begin in the 'server' configuration context
|
||||
- ONLY files that end with '.conf' will be processed!
|
||||
- if you want to keep a file for reference or disable it temporarily,
|
||||
- if you want to keep a file for reference or disable it temporarily,
|
||||
simply change the extension. I like using '.conf.disabled'.
|
||||
- If you don't want to use this directory, you can bind-mount any other
|
||||
- If you don't want to use this directory, you can bind-mount any other
|
||||
directory you want to '/etc/nginx/sites/'
|
||||
|
||||
+215
-182
@@ -1,83 +1,87 @@
|
||||
#!/bin/sh
|
||||
|
||||
### update script for ab-nginx container and utility scripts
|
||||
# version 2.0.0
|
||||
# script by Asif Bacchus
|
||||
###
|
||||
#
|
||||
# update script for ab-nginx container and utility scripts
|
||||
# version 2.1.0
|
||||
# script by Asif Bacchus
|
||||
#
|
||||
|
||||
### functions
|
||||
#
|
||||
# functions
|
||||
errMsg() {
|
||||
printf "\n%s%s%s\n\n" "$err" "$1" "$norm"
|
||||
exit 1
|
||||
printf "\n%s%s%s\n\n" "$err" "$1" "$norm"
|
||||
[ -n "$2" ] && exit "$2" || exit 1
|
||||
}
|
||||
|
||||
errNotify() {
|
||||
printf "%s[ERROR]%s\n" "$err" "$norm"
|
||||
printf "%s[ERROR]%s\n" "$err" "$norm"
|
||||
}
|
||||
|
||||
okMsg() {
|
||||
printf "%s%s%s\n\n" "$ok" "$1" "$norm"
|
||||
printf "%s%s%s\n\n" "$ok" "$1" "$norm"
|
||||
}
|
||||
|
||||
okNotify() {
|
||||
printf "%s[OK]%s\n" "$ok" "$norm"
|
||||
printf "%s[OK]%s\n" "$ok" "$norm"
|
||||
}
|
||||
|
||||
scriptHelp() {
|
||||
textNewline
|
||||
textblock "Update ${containerName} container and helper script files"
|
||||
textblock "${bold}Usage: ${localScriptName} [parameters]${norm}"
|
||||
textNewline
|
||||
textblock "If run with no parameters, the script will update both the container and the helper script files, including this update script."
|
||||
textblockHeader " parameters "
|
||||
textblockParam "-h|-?|--help" "Display this help screen."
|
||||
textblockParam "-c|--container|--container-only" "Update the docker container only."
|
||||
textblockParam "-s|--scripts|--scripts-only" "Update the helper scripts (including this update script) only."
|
||||
textNewline
|
||||
exit 0
|
||||
textNewline
|
||||
textBlock "Update ${containerName} container and helper script files"
|
||||
textBlock "${bold}Usage: ${localScriptName} [parameters]${norm}"
|
||||
textNewline
|
||||
textBlock "If run with no parameters, the script will update both the container and the helper script files, including this update script."
|
||||
textBlockHeader " parameters "
|
||||
textBlockParam "-h|-?|--help" "Display this help screen."
|
||||
textBlockParam "-c|--container|--container-only" "Update the docker container only."
|
||||
textBlockParam "-s|--scripts|--scripts-only" "Update the helper scripts (including this update script) only."
|
||||
textNewline
|
||||
exit 0
|
||||
}
|
||||
|
||||
textblock() {
|
||||
printf "%s\n" "$1" | fold -w "$width" -s
|
||||
textBlock() {
|
||||
printf "%s\n" "$1" | fold -w "$width" -s
|
||||
}
|
||||
|
||||
textblockHeader() {
|
||||
printf "\n%s***%s***%s\n" "$header" "$1" "$norm"
|
||||
textBlockHeader() {
|
||||
printf "\n%s***%s***%s\n" "$header" "$1" "$norm"
|
||||
}
|
||||
|
||||
textblockParam() {
|
||||
printf "%s%-35s%s%s\n" "$info" "$1" "$2" "$norm"
|
||||
textBlockParam() {
|
||||
printf "%s%-35s%s%s\n" "$info" "$1" "$2" "$norm"
|
||||
}
|
||||
|
||||
textNewline() {
|
||||
printf "\n"
|
||||
printf "\n"
|
||||
}
|
||||
|
||||
### text formatting presets
|
||||
#
|
||||
# text formatting presets
|
||||
if command -v tput >/dev/null 2>&1; then
|
||||
bold=$(tput bold)
|
||||
err=$(tput bold)$(tput setaf 1)
|
||||
info=$(tput bold)$(tput setaf 6)
|
||||
header=$(tput bold)$(tput setaf 5)
|
||||
norm=$(tput sgr0)
|
||||
ok=$(tput sgr0)$(tput setaf 2)
|
||||
warn=$(tput bold)$(tput setaf 3)
|
||||
width=$(tput cols)
|
||||
bold=$(tput bold)
|
||||
err=$(tput bold)$(tput setaf 1)
|
||||
info=$(tput bold)$(tput setaf 6)
|
||||
header=$(tput bold)$(tput setaf 5)
|
||||
norm=$(tput sgr0)
|
||||
ok=$(tput sgr0)$(tput setaf 2)
|
||||
warn=$(tput bold)$(tput setaf 3)
|
||||
width=$(tput cols)
|
||||
else
|
||||
bold=''
|
||||
err=''
|
||||
info=''
|
||||
header=''
|
||||
norm=''
|
||||
ok=''
|
||||
warn=''
|
||||
width=80
|
||||
bold=''
|
||||
err=''
|
||||
info=''
|
||||
header=''
|
||||
norm=''
|
||||
ok=''
|
||||
warn=''
|
||||
width=80
|
||||
fi
|
||||
|
||||
### pre-requisites
|
||||
#
|
||||
# pre-requisites
|
||||
# check if wget is installed
|
||||
if ! command -v wget >/dev/null 2>&1; then
|
||||
errMsg "Sorry, this script requires that 'wget' is installed in order to download updates. Exiting."
|
||||
errMsg "Sorry, this script requires that 'wget' is installed in order to download updates. Exiting."
|
||||
fi
|
||||
|
||||
# zero counters
|
||||
@@ -90,8 +94,8 @@ updateSuccess=0
|
||||
# reference constants
|
||||
dockerNamespace='nginx'
|
||||
containerName='ab-nginx'
|
||||
containerUpdatePath="docker.asifbacchus.app/$dockerNamespace/$containerName:latest"
|
||||
server="https://asifbacchus.app/updates/docker/$dockerNamespace/$containerName/"
|
||||
containerUpdatePath="docker.asifbacchus.dev/$dockerNamespace/$containerName:latest"
|
||||
server="https://asifbacchus.dev/public/docker/$dockerNamespace/$containerName/"
|
||||
checksumFilename='checksums.sha256'
|
||||
|
||||
# operation triggers
|
||||
@@ -102,149 +106,178 @@ doScriptUpdate=1
|
||||
localScriptName="$(basename "$0")"
|
||||
repoScriptName='update.sh'
|
||||
|
||||
### process startup parameters
|
||||
#
|
||||
# process startup parameters
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h | -\? | --help)
|
||||
# display inline help
|
||||
scriptHelp
|
||||
;;
|
||||
-s | --scripts | --scripts-only)
|
||||
# update scripts only, skip docker container update
|
||||
doDockerUpdate=0
|
||||
;;
|
||||
-c | --container | --container-only)
|
||||
# update docker container only, skip script update
|
||||
doScriptUpdate=0
|
||||
;;
|
||||
*)
|
||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||
printf "%sUse '--help' for valid options%s\n\n" "$info" "$norm"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
case "$1" in
|
||||
-h | -\? | --help)
|
||||
# display inline help
|
||||
scriptHelp
|
||||
;;
|
||||
-s | --scripts | --scripts-only)
|
||||
# update scripts only, skip docker container update
|
||||
doDockerUpdate=0
|
||||
;;
|
||||
-c | --container | --container-only)
|
||||
# update docker container only, skip script update
|
||||
doScriptUpdate=0
|
||||
;;
|
||||
*)
|
||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||
printf "%sUse '--help' for valid options%s\n\n" "$info" "$norm"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
### update container
|
||||
#
|
||||
# update container
|
||||
if [ "$doDockerUpdate" -eq 1 ]; then
|
||||
# check if docker is installed
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
errMsg "Sorry, it appears that docker is not installed on this machine! Exiting."
|
||||
fi
|
||||
|
||||
# is user root or in the docker group?
|
||||
if [ ! "$(id -u)" -eq 0 ]; then
|
||||
if ! id -Gn | grep docker >/dev/null; then
|
||||
errMsg "You must either be root or in the 'docker' group to pull container updates."
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "%s\n*** Updating %s container ***\n\n%s" "$info" "$containerName" "$norm"
|
||||
if ! docker pull "$containerUpdatePath"; then
|
||||
errMsg "There was an error updating the container. Try again later."
|
||||
else
|
||||
okMsg "Container updated!"
|
||||
fi
|
||||
fi
|
||||
|
||||
### update scripts
|
||||
if [ "$doScriptUpdate" -eq 1 ]; then
|
||||
printf "%s*** Updating %s service scripts ***%s\n" "$info" "$containerName" "$norm"
|
||||
|
||||
## download latest checksums
|
||||
printf "Getting latest checksums... "
|
||||
if ! wget --quiet --tries=3 --timeout=10 -N "${server}${checksumFilename}"; then
|
||||
errNotify
|
||||
errMsg "Unable to download checksums. Try again later."
|
||||
else
|
||||
okNotify
|
||||
fi
|
||||
|
||||
## check for updates to this script
|
||||
printf "Checking for updates to this script... "
|
||||
repoScriptChecksum=$(grep "$repoScriptName" "$checksumFilename" | grep -o '^\S*')
|
||||
localScriptChecksum=$(sha256sum "$localScriptName" | grep -o '^\S*')
|
||||
if [ "$localScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||
printf "[NONE]\n"
|
||||
else
|
||||
printf "[AVAILABLE]\n"
|
||||
printf "Getting updated script... "
|
||||
# download updated script
|
||||
if ! wget --quiet --tries=3 --timeout=10 -O "update.sh.tmp" "${server}${repoScriptName}"; then
|
||||
errNotify
|
||||
# delete failed download as necessary
|
||||
rm -f ./update.sh.tmp 2>/dev/null
|
||||
errMsg "Unable to download script update. Try again later."
|
||||
else
|
||||
# verify download
|
||||
dlScriptChecksum=$(sha256sum "update.sh.tmp" | grep -o '^\S*')
|
||||
if ! [ "$dlScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||
printf "[ERROR]\n"
|
||||
# delete corrupt download as necessary
|
||||
rm -f ./update.sh.tmp 2>/dev/null
|
||||
errMsg "Checksum mismatch! Try again later."
|
||||
else
|
||||
okNotify
|
||||
printf "\n%s*** This script has been updated. Please re-run it to load the updated version of this file. ***%s\n\n" "$warn" "$norm"
|
||||
# overwrite this script with updated script
|
||||
mv -f ./update.sh.tmp "$localScriptName"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
## update files
|
||||
while IFS=' ' read -r field1 field2; do
|
||||
printf "\nChecking '%s' for updates... " "$field2"
|
||||
updateFilename="$field2"
|
||||
repoFileChecksum="$field1"
|
||||
if [ -f "$updateFilename" ]; then
|
||||
localFileChecksum=$(sha256sum "$updateFilename" | grep -o '^\S*')
|
||||
else
|
||||
localFileChecksum=0
|
||||
# check if docker is installed
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
errMsg "Sorry, it appears that docker is not installed on this machine! Exiting." 2
|
||||
fi
|
||||
|
||||
# update file if necessary
|
||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||
printf "[AVAILABLE]\n"
|
||||
updatesAvailable=$((updatesAvailable + 1))
|
||||
# download update
|
||||
printf "Downloading updated '%s'... " "$updateFilename"
|
||||
if ! wget --quiet --tries=3 --timeout=10 -O "$updateFilename.tmp" "${server}${updateFilename}"; then
|
||||
errNotify
|
||||
downloadFailed=$((downloadFailed + 1))
|
||||
# delete failed download file as necessary
|
||||
rm -f "$updateFilename.tmp" 2>&1
|
||||
else
|
||||
okNotify
|
||||
downloadSuccess=$((downloadSuccess + 1))
|
||||
# verify download
|
||||
printf "Verifying '%s'... " "$updateFilename"
|
||||
localFileChecksum=$(sha256sum "$updateFilename.tmp" | grep -o '^\S*')
|
||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||
errNotify
|
||||
updateFailed=$((updateFailed + 1))
|
||||
# delete corrupted download file as necessary
|
||||
rm -f "$updateFilename.tmp" 2>&1
|
||||
else
|
||||
okNotify
|
||||
updateSuccess=$((updateSuccess + 1))
|
||||
# overwrite old version of file
|
||||
mv -f "$updateFilename.tmp" "$updateFilename"
|
||||
# is user root or in the docker group?
|
||||
if [ ! "$(id -u)" -eq 0 ]; then
|
||||
if ! id -Gn | grep docker >/dev/null; then
|
||||
errMsg "You must either be root or in the 'docker' group to pull container updates." 2
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printf "[NONE]\n"
|
||||
fi
|
||||
done <"$checksumFilename"
|
||||
|
||||
printf "%s\n*** Updating %s container ***\n\n%s" "$info" "$containerName" "$norm"
|
||||
if ! docker pull "$containerUpdatePath"; then
|
||||
errMsg "There was an error updating the container. Try again later." 31
|
||||
else
|
||||
okMsg "Container updated!"
|
||||
fi
|
||||
fi
|
||||
|
||||
### display results
|
||||
#
|
||||
# update scripts
|
||||
if [ "$doScriptUpdate" -eq 1 ]; then
|
||||
printf "\n%s*** Results ***%s\n" "$info" "$norm"
|
||||
printf "\tUpdates: %s available\n" "$updatesAvailable"
|
||||
printf "\tDownloads: %s%s successful%s, %s%s failed%s\n" "$ok" "$downloadSuccess" "$norm" "$err" "$downloadFailed" "$norm"
|
||||
printf "\tUpdates: %s%s applied%s, %s%s failed%s\n" "$ok" "$updateSuccess" "$norm" "$err" "$updateFailed" "$norm"
|
||||
printf "%s*** Updating %s service scripts ***%s\n" "$info" "$containerName" "$norm"
|
||||
|
||||
## download latest checksums
|
||||
printf "Getting latest checksums... "
|
||||
if ! wget --quiet --tries=3 --timeout=10 -N "${server}${checksumFilename}"; then
|
||||
errNotify
|
||||
errMsg "Unable to download checksums. Try again later." 41
|
||||
else
|
||||
okNotify
|
||||
fi
|
||||
|
||||
## check for updates to this script
|
||||
printf "Checking for updates to this script... "
|
||||
repoScriptChecksum=$(grep "$repoScriptName" "$checksumFilename" | grep -o '^\S*')
|
||||
localScriptChecksum=$(sha256sum "$localScriptName" | grep -o '^\S*')
|
||||
if [ "$localScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||
printf "[NONE]\n"
|
||||
else
|
||||
printf "[AVAILABLE]\n"
|
||||
printf "Getting updated script... "
|
||||
# download updated script
|
||||
if ! wget --quiet --tries=3 --timeout=10 -O "update.sh.tmp" "${server}${repoScriptName}"; then
|
||||
errNotify
|
||||
# delete failed download as necessary
|
||||
rm -f ./update.sh.tmp 2>/dev/null
|
||||
errMsg "Unable to download script update. Try again later." 42
|
||||
else
|
||||
# verify download
|
||||
dlScriptChecksum=$(sha256sum "update.sh.tmp" | grep -o '^\S*')
|
||||
if ! [ "$dlScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||
printf "[ERROR]\n"
|
||||
# delete corrupt download as necessary
|
||||
rm -f ./update.sh.tmp 2>/dev/null
|
||||
errMsg "Checksum mismatch! Try again later." 42
|
||||
else
|
||||
okNotify
|
||||
printf "\n%s*** This script has been updated. Please re-run it to load the updated version of this file. ***%s\n\n" "$warn" "$norm"
|
||||
# overwrite this script with updated script
|
||||
mv -f ./update.sh.tmp "$localScriptName"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
## update files
|
||||
while IFS=' ' read -r field1 field2; do
|
||||
printf "\nChecking '%s' for updates... " "$field2"
|
||||
updateFilename="$field2"
|
||||
repoFileChecksum="$field1"
|
||||
if [ -f "$updateFilename" ]; then
|
||||
localFileChecksum=$(sha256sum "$updateFilename" | grep -o '^\S*')
|
||||
else
|
||||
localFileChecksum=0
|
||||
fi
|
||||
|
||||
# update file if necessary
|
||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||
printf "[AVAILABLE]\n"
|
||||
updatesAvailable=$((updatesAvailable + 1))
|
||||
# download update
|
||||
printf "Downloading updated '%s'... " "$updateFilename"
|
||||
if ! wget --quiet --tries=3 --timeout=10 -O "$updateFilename.tmp" "${server}${updateFilename}"; then
|
||||
errNotify
|
||||
downloadFailed=$((downloadFailed + 1))
|
||||
# delete failed download file as necessary
|
||||
rm -f "$updateFilename.tmp" 2>&1
|
||||
else
|
||||
okNotify
|
||||
downloadSuccess=$((downloadSuccess + 1))
|
||||
# verify download
|
||||
printf "Verifying '%s'... " "$updateFilename"
|
||||
localFileChecksum=$(sha256sum "$updateFilename.tmp" | grep -o '^\S*')
|
||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||
errNotify
|
||||
updateFailed=$((updateFailed + 1))
|
||||
# delete corrupted download file as necessary
|
||||
rm -f "$updateFilename.tmp" 2>&1
|
||||
else
|
||||
okNotify
|
||||
updateSuccess=$((updateSuccess + 1))
|
||||
# overwrite old version of file
|
||||
mv -f "$updateFilename.tmp" "$updateFilename"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printf "[NONE]\n"
|
||||
fi
|
||||
done <"$checksumFilename"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
#
|
||||
# display results
|
||||
if [ "$doScriptUpdate" -eq 1 ]; then
|
||||
printf "\n%s*** Results ***%s\n" "$info" "$norm"
|
||||
printf "\tUpdates: %s available\n" "$updatesAvailable"
|
||||
printf "\tDownloads: %s%s successful%s, %s%s failed%s\n" "$ok" "$downloadSuccess" "$norm" "$err" "$downloadFailed" "$norm"
|
||||
printf "\tUpdates: %s%s applied%s, %s%s failed%s\n" "$ok" "$updateSuccess" "$norm" "$err" "$updateFailed" "$norm"
|
||||
fi
|
||||
|
||||
#
|
||||
# exit
|
||||
if [ "$downloadFailed" -gt 0 ]; then
|
||||
exit 43
|
||||
elif [ "$updateFailed" -gt 0 ]; then
|
||||
exit 44
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
# this is a trap for mis-coding... should never get an exit code 99!
|
||||
exit 99
|
||||
|
||||
#
|
||||
# exit return codes
|
||||
# 0: normal exit, no errors
|
||||
# 1: missing or invalid parameter
|
||||
# 2: docker not found or no docker permissions
|
||||
# 31: unable to update docker container
|
||||
# 4x: helper files errors
|
||||
# 41: unable to download checksums
|
||||
# 42: update script: unable to download or bad checksum
|
||||
# 43: update helpers: unable to download
|
||||
# 44: update helpers: bad checksum, no update
|
||||
# 99: coding mistake trap -- this return code should never happen!
|
||||
|
||||
#EOF
|
||||
|
||||
Reference in New Issue
Block a user