First!
This commit is contained in:
parent
7fc11199a6
commit
bb78a2e3f9
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
**/.git
|
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
|
# 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 "${BIN}" -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