First!
This commit is contained in:
parent
7fc11199a6
commit
10de617be5
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
FROM openresty/openresty:alpine-fat
|
||||
LABEL maintainer "Jiang Yio <inportb@gmail.com>"
|
||||
|
||||
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"]
|
26
README.md
26
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
|
||||
```
|
||||
|
41
app/acme-autocert.sh
Executable file
41
app/acme-autocert.sh
Executable file
@ -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
|
3
app/acme-renew.sh
Executable file
3
app/acme-renew.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
/root/.acme.sh/acme.sh --cron "$@"
|
19
app/add-proxy.sh
Executable file
19
app/add-proxy.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
NAME="$1"
|
||||
URL="$2"
|
||||
|
||||
. /root/common.sh
|
||||
|
||||
cat > "${CONF}/conf.d/auto.${NAME}.conf" <<EOF
|
||||
server {
|
||||
server_name ${NAME};
|
||||
server_tokens off;
|
||||
include snippets/ssl.conf;
|
||||
include snippets/gzip.conf;
|
||||
location / {
|
||||
proxy_pass ${URL};
|
||||
include snippets/reverse-proxy.conf;
|
||||
}
|
||||
}
|
||||
EOF
|
2
app/common.sh
Normal file
2
app/common.sh
Normal file
@ -0,0 +1,2 @@
|
||||
BIN=/usr/local/openresty/bin/openresty
|
||||
CONF=/usr/local/openresty/nginx/conf
|
9
app/default/conf.d/01-http.conf
Normal file
9
app/default/conf.d/01-http.conf
Normal file
@ -0,0 +1,9 @@
|
||||
resolver local=on;
|
||||
lua_shared_dict sessions 10m;
|
||||
|
||||
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=proxycache:5m max_size=5g inactive=60m use_temp_path=off;
|
||||
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
6
app/default/snippets/gzip.conf
Normal file
6
app/default/snippets/gzip.conf
Normal file
@ -0,0 +1,6 @@
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 10240;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
|
||||
gzip_disable "MSIE [1-6]\.";
|
6
app/default/snippets/proxycache.conf
Normal file
6
app/default/snippets/proxycache.conf
Normal file
@ -0,0 +1,6 @@
|
||||
proxy_cache proxycache;
|
||||
proxy_cache_revalidate on;
|
||||
proxy_cache_min_uses 3;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
proxy_cache_background_update on;
|
||||
proxy_cache_lock on;
|
7
app/default/snippets/reverse-proxy.conf
Normal file
7
app/default/snippets/reverse-proxy.conf
Normal file
@ -0,0 +1,7 @@
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
#proxy_set_header X-Forwarded-Scheme $scheme;
|
||||
proxy_set_header X-Scheme $scheme;
|
26
app/default/snippets/ssl.conf
Normal file
26
app/default/snippets/ssl.conf
Normal file
@ -0,0 +1,26 @@
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
|
||||
if ($scheme != "https") {
|
||||
return 302 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
# https://ssl-config.mozilla.org/
|
||||
ssl_certificate ssl.cer;
|
||||
ssl_certificate_key ssl.key;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
add_header Strict-Transport-Security "max-age=63072000" always; # HSTS (needs ngx_http_headers_module)
|
||||
ssl_stapling on; # OCSP stapling
|
||||
ssl_stapling_verify on;
|
||||
|
||||
location /.well-known/ {
|
||||
root /var/www;
|
||||
}
|
3
app/default/snippets/websocket-proxy.conf
Normal file
3
app/default/snippets/websocket-proxy.conf
Normal file
@ -0,0 +1,3 @@
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
18
app/default/ssl.cer
Normal file
18
app/default/ssl.cer
Normal file
@ -0,0 +1,18 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC2TCCAcGgAwIBAgIUD5GwT+AINCz3va62MacN3fcSnoEwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJdnBzMTczMTM0MB4XDTIwMDIxODA0MzEwMloXDTMwMDIx
|
||||
NTA0MzEwMlowFDESMBAGA1UEAwwJdnBzMTczMTM0MIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAzqxnIhy3gT4e3HYdz5G8/T6zo4a1QMaTcFixdLzH5IuE
|
||||
c+9eRMJC23AbJCcscYaXmUb8D8vi03PSIDZZLxQiMeiKXVACMnX04IWTMit11SXa
|
||||
MWgXkSiA1JUxMyTRYX2u1lMXU9dQl+J7/9HIxgPCZqOe4y87Zl2b5NW8Lzo3sGIK
|
||||
RIJzmgJyywPDHLcU5VTwlJLO/929GwL9aWy+ExXOeBF3vo0bhQBa3pUHviVpq8iw
|
||||
1OTwl965BgbCwVZgmRxxY/PivURrh4dPSDpnOwJHxlRixEHoq9WrHC9IUgVf9p4S
|
||||
MFKIjLYPcf1gmHjmklfCi085ze8Uyx7bxzE2BEe3owIDAQABoyMwITAJBgNVHRME
|
||||
AjAAMBQGA1UdEQQNMAuCCXZwczE3MzEzNDANBgkqhkiG9w0BAQsFAAOCAQEAHd5R
|
||||
ztdZrd2m5BlOwTHKht4xmtdfh15jeEADskQqar1JFrHy3Os+EtMHBh0zd4ZDAXke
|
||||
WuheLO/MxOa22g190Jx+FyZd2hDzbMliRElQGzyTe6q0fFPEpCOfzzG7q4f0iouR
|
||||
V6825A6FC9zKsCcUS2jEQKwNpHojYQApkRsyzeq44vRkfUlcHvwd5fXET/uFlNxK
|
||||
b2i7fX4hI/0tM6IAIVsq48hhWpx5j0ilebzW1v51xVGs0kDzOTh0weBcqjFX33nz
|
||||
hJXFoGYoqexERI1u8Wnc9Zw9dVKX8ovclIAe6u2AzWXzjBY1PmBW+JKSjYNlaejr
|
||||
pWgePOeIs67AdY0lRQ==
|
||||
-----END CERTIFICATE-----
|
28
app/default/ssl.key
Normal file
28
app/default/ssl.key
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOrGciHLeBPh7c
|
||||
dh3Pkbz9PrOjhrVAxpNwWLF0vMfki4Rz715EwkLbcBskJyxxhpeZRvwPy+LTc9Ig
|
||||
NlkvFCIx6IpdUAIydfTghZMyK3XVJdoxaBeRKIDUlTEzJNFhfa7WUxdT11CX4nv/
|
||||
0cjGA8Jmo57jLztmXZvk1bwvOjewYgpEgnOaAnLLA8MctxTlVPCUks7/3b0bAv1p
|
||||
bL4TFc54EXe+jRuFAFrelQe+JWmryLDU5PCX3rkGBsLBVmCZHHFj8+K9RGuHh09I
|
||||
Omc7AkfGVGLEQeir1ascL0hSBV/2nhIwUoiMtg9x/WCYeOaSV8KLTznN7xTLHtvH
|
||||
MTYER7ejAgMBAAECggEAM1SEZOeG+BWKqqy3aLdEng01ppata8ImGlAc+uZsKyov
|
||||
om/AFQm+eyvTwd3s3uFTw6Dqt62mz2fDt3ZoHhY9C/I6c0SM1yWOxTjHvz0mDeNR
|
||||
1tWIjOfnX2USjCZHzpPdmaOXdp5SiPaaX4Yl/HAwlzdqHfi8Iwd60ZH4JC6saCTv
|
||||
L1vQzj+nuJwswSaoYxeO/3lBN9W9TL84fPX9g5alh4AdMzQyluFqNmhq2cZqTcDz
|
||||
sHZ3vXboNAsbRu+RQTWqmG+bzfXDGpbXzxDD0jQbSJMSNAgZx3g1LCb0sdBlXh2R
|
||||
Hy1dED3Vt5+07UwAB5IVUUSnyNTg4F493l9hUewb8QKBgQDnWP2PPsHtwM9t9xbi
|
||||
H5dFxrVRce7mV0dCi84g6qnGlcT0r19jNuxkIUdNYO1SywC18MHPTrwAXhcyKz0+
|
||||
jISrYKGa8Zla8sPwVwoidFyHWkZcJMy55YlVowYGsZkBhzVqIH7C4d9lgpFof0G3
|
||||
KKsVU4TOpqrcNKqiO6PCuppxewKBgQDkslFBXoAbeKVktliAwR4nwqW5jeLuUSoa
|
||||
dLVNMGi96griiYixOe5DVhKegeBPz0m2A1Kj58lgnO/v7VOXBQt4ONr3WuhGqca2
|
||||
8K0d9eEBijMBVjWBEZpJO0E+V9quIpyF050pZyntTjjESpYEp+hFTKVlCxp7+iJn
|
||||
znBHv6zV+QKBgAKFO6311xMKCLh/+qXYBkPiWFNc1Gd6B/K3pzVAmTzqoMyxpG5m
|
||||
SMkGe8piBfPi9k0FJHdnujCe1c3cHryxtzhOwzP28d7FylCyAhBCCEgJOb8DP5++
|
||||
2nIuZoBoKuyTVoejdv4Ui+SFOaRTzpl6PfLriATgV/gyMrG1yKD0e35FAoGAMjVD
|
||||
yYoprd5K0VWHEJ1VNX1yTM5tp8yB5dUBiLS8ChW71ghDzkTdnkLjS5FP4bWshR0t
|
||||
o3Zbq65Iru/3jgw5fGdfCzcWD41uZvNnzlAQ2fmxQPXgQTnQGYu8wyceh2Rp4KeY
|
||||
tWJEviiSJeYKEXObdrthBFHvupArxYZ4+AeItmECgYEA1dFJVGM2mvp4SumdaNYD
|
||||
qy3Tvy2wpB6TY0bPBvsRQoeAkV/mKOuwi71iBEcZbkJP6aqqccmKwlb8d2s4mfdB
|
||||
+Ok84Lnz2BO6sORklDAltS3G3b1LC9wQyl4hO+Drf4zjXkH0LEk+ZQMhTJazU5mW
|
||||
WQUFIyLfPb9HtUk0lhBcZyM=
|
||||
-----END PRIVATE KEY-----
|
17
app/init.sh
Executable file
17
app/init.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /root/common.sh
|
||||
|
||||
false | cp -ai /root/default/* "${CONF}/" 2>/dev/null
|
||||
|
||||
if ! [ -e "${CONF}/sites-enabled" ]; then
|
||||
ln -s conf.d "${CONF}/sites-enabled"
|
||||
fi
|
||||
|
||||
mkdir -p /var/log/nginx /var/cache/nginx
|
||||
|
||||
~/reloader.sh &
|
||||
(sleep 30; RELOAD_FIRST=no /root/acme-autocert.sh) &
|
||||
/usr/sbin/crond -b
|
||||
|
||||
"${BIN}" -g 'daemon off;'
|
14
app/reloader.sh
Executable file
14
app/reloader.sh
Executable file
@ -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 nginx -t; then
|
||||
echo "reloader: new configuration"
|
||||
"${BIN}" -s reload
|
||||
RELOAD_FIRST=no /root/acme-autocert.sh
|
||||
else
|
||||
echo "reloader: invalid configuration"
|
||||
fi
|
||||
done
|
Loading…
Reference in New Issue
Block a user