diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f3b6411 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +**/.git diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..afb64c0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM openresty/openresty:alpine-fat +LABEL maintainer "Jiang Yio " + +RUN apk add --no-cache openssl socat wget inotify-tools && \ + luarocks install lua-resty-openidc && \ + luarocks install lua-resty-session && \ + rm /etc/nginx/conf.d/default.conf && \ + mv /etc/nginx/conf.d /usr/local/openresty/nginx/conf/ && \ + ln -s /usr/local/openresty/nginx/conf/conf.d /etc/nginx/ && \ + echo '0 12 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh' >> /etc/crontabs/root +RUN wget -O - https://get.acme.sh | sh +COPY app /root + +WORKDIR /root + +ENTRYPOINT ["/root/init.sh"] diff --git a/README.md b/README.md index 6ad7423..ae4c8ef 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ # docker-nginx-auto +Nginx with tricks + +- OpenResty +- Snippets for TLS/SSL, gzip, reverse proxy, websocket proxy, and proxy cache +- Automatic Let's Encrypt certificate +- Automatic reload on configuration change + +Production: + +```sh +docker run -d --name=docker-nginx-auto \ + -e ACME_EMAIL=user@host \ + -p 80:80 -p 443:443 \ + -v nginx-config:/usr/local/openresty/nginx/conf \ + docker-nginx-auto +``` + +Staging: + +```sh +docker run -d --name=docker-nginx-auto \ + -e ACME_STAGING=true \ + -p 80:80 -p 443:443 \ + -v nginx-config:/usr/local/openresty/nginx/conf \ + docker-nginx-auto +``` diff --git a/app/acme-autocert.sh b/app/acme-autocert.sh new file mode 100755 index 0000000..909f691 --- /dev/null +++ b/app/acme-autocert.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +. /root/common.sh + +get_domains() { + cat /etc/nginx/conf.d/* \ + | sed 's/^[[:blank:]]*//' \ + | grep ^server_name \ + | grep -v 'NOSSL' \ + | cut -d';' -f1 \ + | awk '{for(i=2; i<=NF; i++) print $i}' \ + | awk '{$1=$1};1' \ + | grep -E '^[[:alnum:]_-]+([.][[:alnum:]_-]+)*$' \ + | sort | uniq +} + +get_args() { + if [ "${ACME_STAGING}" != "" ]; then + echo --staging + fi + if [ "${ACME_EMAIL}" != "" ]; then + echo --email + echo "${ACME_EMAIL}" + fi + echo --issue + echo --webroot + echo /var/www + for h in `get_domains`; do + echo -d + echo "$h" + done +} + +if [ "${RELOAD_FIRST}" != "no" ]; then + "${BIN}" -s reload +fi +if /root/.acme.sh/acme.sh \ + --key-file "${CONF}/ssl.key" --fullchain-file "${CONF}/ssl.cer" \ + "$@" `get_args`; then + "${BIN}" -s reload +fi diff --git a/app/acme-renew.sh b/app/acme-renew.sh new file mode 100755 index 0000000..6363276 --- /dev/null +++ b/app/acme-renew.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/root/.acme.sh/acme.sh --cron "$@" diff --git a/app/add-proxy.sh b/app/add-proxy.sh new file mode 100755 index 0000000..58cbe2a --- /dev/null +++ b/app/add-proxy.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +NAME="$1" +URL="$2" + +. /root/common.sh + +cat > "${CONF}/conf.d/auto.${NAME}.conf" </dev/null + +if ! [ -e "${CONF}/sites-enabled" ]; then + ln -s conf.d "${CONF}/sites-enabled" +fi + +mkdir -p /var/log/nginx /var/cache/nginx + +/root/reloader.sh & +(sleep 30; RELOAD_FIRST=no /root/acme-autocert.sh) & +/usr/sbin/crond -b + +"${BIN}" -g 'daemon off;' "$@" diff --git a/app/reloader.sh b/app/reloader.sh new file mode 100755 index 0000000..8e41a0b --- /dev/null +++ b/app/reloader.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. /root/common.sh + +while inotifywait -q -r -e create -e modify -e delete -e move \ + --exclude .swp "${CONF}"; do + if "${BIN}" -t; then + echo "reloader: new configuration" + "${BIN}" -s reload + RELOAD_FIRST=no /root/acme-autocert.sh + else + echo "reloader: invalid configuration" + fi +done