[mod] proxy nginx config is now generated based on domains.env
- domains and servers in domains.env are mapped 1:1 - moved domains.env to ./files/domains.env - renamed kweb to web for a more generic approach
This commit is contained in:
@@ -1,2 +0,0 @@
|
|||||||
DOMAINS=example.com www api test\n example.dev www api test
|
|
||||||
SERVER=kweb\n test
|
|
||||||
@@ -9,7 +9,10 @@ services:
|
|||||||
USER_UID: ${UID_PROXY:-12001}
|
USER_UID: ${UID_PROXY:-12001}
|
||||||
GROUP_UID: ${UID_PROXY:-12001}
|
GROUP_UID: ${UID_PROXY:-12001}
|
||||||
env_file:
|
env_file:
|
||||||
- ./certbot/files/domains.env
|
# contains DOMAINS and SERVER variable
|
||||||
|
# DOMAINS: rootA.com www api\nrootB.com www mail
|
||||||
|
# SERVER: webA webB
|
||||||
|
- ./files/domains.env
|
||||||
restart: always
|
restart: always
|
||||||
image: proxy
|
image: proxy
|
||||||
container_name: proxy
|
container_name: proxy
|
||||||
@@ -17,7 +20,7 @@ services:
|
|||||||
- "80:8080"
|
- "80:8080"
|
||||||
- "443:8443"
|
- "443:8443"
|
||||||
networks:
|
networks:
|
||||||
- service_kweb
|
- service_web
|
||||||
- service_certbot
|
- service_certbot
|
||||||
volumes:
|
volumes:
|
||||||
# cert volume
|
# cert volume
|
||||||
@@ -34,7 +37,12 @@ services:
|
|||||||
USER_UID: ${UID_CERTBOT:-12002}
|
USER_UID: ${UID_CERTBOT:-12002}
|
||||||
GROUP_UID: ${UID_PROXY:-12002}
|
GROUP_UID: ${UID_PROXY:-12002}
|
||||||
env_file:
|
env_file:
|
||||||
- ./certbot/files/domains.env
|
# contains DOMAINS and SERVER variable
|
||||||
|
# DOMAINS: rootA.com www api\nrootB.com www mail
|
||||||
|
# SERVER (not used by certbot): webA webB
|
||||||
|
- ./files/domains.env
|
||||||
|
# cerbot container will be set to testing
|
||||||
|
# unless PRODUCTION var is set (any value) in the environment
|
||||||
- ./production.env # set PRODUCTION= here
|
- ./production.env # set PRODUCTION= here
|
||||||
restart: always
|
restart: always
|
||||||
image: certbot
|
image: certbot
|
||||||
@@ -53,19 +61,19 @@ services:
|
|||||||
|
|
||||||
# TODO: put this in its own docker-compose
|
# TODO: put this in its own docker-compose
|
||||||
# as the proxy does not require it
|
# as the proxy does not require it
|
||||||
kweb:
|
web:
|
||||||
build:
|
build:
|
||||||
context: ./kweb
|
context: ./web
|
||||||
args:
|
args:
|
||||||
USER_UID: ${UID_KWEB:-12003}
|
USER_UID: ${UID_WEB:-12003}
|
||||||
GROUP_UID: ${UID_KWEB:-12003}
|
GROUP_UID: ${UID_WEB:-12003}
|
||||||
restart: always
|
restart: always
|
||||||
image: kweb
|
image: web
|
||||||
container_name: kweb
|
container_name: web
|
||||||
networks:
|
networks:
|
||||||
- service_kweb
|
- service_web
|
||||||
volumes:
|
volumes:
|
||||||
- service_kweb:/service/html:ro
|
- service_web:/service/html:ro
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# proxy volumes
|
# proxy volumes
|
||||||
@@ -83,11 +91,11 @@ volumes:
|
|||||||
certbot_logs:
|
certbot_logs:
|
||||||
name: certbot_logs
|
name: certbot_logs
|
||||||
# service volumes
|
# service volumes
|
||||||
service_kweb:
|
service_web:
|
||||||
name: service_kweb
|
name: service_web
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
service_kweb:
|
service_web:
|
||||||
name: service_kweb
|
name: service_web
|
||||||
service_certbot:
|
service_certbot:
|
||||||
name: service_certbot
|
name: service_certbot
|
||||||
4
files/domains.env
Normal file
4
files/domains.env
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# domains are seperated with \n
|
||||||
|
DOMAINS=example.com www api test
|
||||||
|
# server values are seperated with ' ' (space) (one server per domain)
|
||||||
|
SERVER=web
|
||||||
@@ -9,9 +9,11 @@ server_retries=10
|
|||||||
log_file="" # leave empty for stdout
|
log_file="" # leave empty for stdout
|
||||||
|
|
||||||
# variables
|
# variables
|
||||||
|
config_file="$temp_path/nginx.conf"
|
||||||
domain_file="$temp_path/domains.txt"
|
domain_file="$temp_path/domains.txt"
|
||||||
certs_updated="$cert_root_path/.updated"
|
certs_updated="$cert_root_path/.updated"
|
||||||
certs_daemon_pid=-1
|
certs_daemon_pid=-1
|
||||||
|
server_configs=""
|
||||||
|
|
||||||
#functions
|
#functions
|
||||||
function log()
|
function log()
|
||||||
@@ -41,6 +43,24 @@ function log()
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# this is a helper function as dash does not support arrays
|
||||||
|
function get_element()
|
||||||
|
{
|
||||||
|
element="$1"
|
||||||
|
seperator="$2"; shift; shift
|
||||||
|
array=$@
|
||||||
|
old_IFS=$IFS
|
||||||
|
IFS="$seperator"
|
||||||
|
set -- $array
|
||||||
|
while [ "$element" -gt 0 ]; do
|
||||||
|
shift
|
||||||
|
element=$(( element - 1 ))
|
||||||
|
done
|
||||||
|
result=$1
|
||||||
|
IFS=$old_IFS
|
||||||
|
echo $result
|
||||||
|
}
|
||||||
|
|
||||||
function sleep_wait()
|
function sleep_wait()
|
||||||
{
|
{
|
||||||
# waiting on sleep to be able to handle SIGTERM
|
# waiting on sleep to be able to handle SIGTERM
|
||||||
@@ -85,13 +105,15 @@ function read_file()
|
|||||||
local func=$1
|
local func=$1
|
||||||
local file=$2
|
local file=$2
|
||||||
local result=0
|
local result=0
|
||||||
|
local count=0
|
||||||
|
|
||||||
while read -r line || [[ -n "$line" ]]; do
|
while read -r line || [[ -n "$line" ]]; do
|
||||||
|
count=$(( count+1 ))
|
||||||
# skip empty lines if READ_EMPTY_LINES is not set
|
# skip empty lines if READ_EMPTY_LINES is not set
|
||||||
[ -z ${READ_EMPTY_LINES+x} ] && [ "${#line}" -lt 1 ] && continue
|
[ -z ${READ_EMPTY_LINES+x} ] && [ "${#line}" -lt 1 ] && continue
|
||||||
log read_file "LINE: $line"
|
log read_file "LINE[$count]: $line"
|
||||||
log read_file "FUNC START [$func]"
|
log read_file "FUNC START [$func]"
|
||||||
if $func $line; then
|
if $func $count $line; then
|
||||||
log read_file "FUNC END [$func]"
|
log read_file "FUNC END [$func]"
|
||||||
else
|
else
|
||||||
result=1
|
result=1
|
||||||
@@ -102,9 +124,77 @@ function read_file()
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rng()
|
||||||
|
{
|
||||||
|
rng_n=$(od -An -N2 -i < /dev/urandom)
|
||||||
|
echo $rng_n
|
||||||
|
}
|
||||||
|
|
||||||
|
function gen_server_config()
|
||||||
|
{
|
||||||
|
local server=$1; shift
|
||||||
|
local root_domain=$1; shift
|
||||||
|
local domain_list="$@"
|
||||||
|
local domain_count=0
|
||||||
|
local domains="$root_domain"
|
||||||
|
|
||||||
|
# no arrays in dash
|
||||||
|
local subdomain=$(get_element $domain_count " " $domain_list)
|
||||||
|
while [ ${#subdomain} -gt 0 ]; do
|
||||||
|
domains="$domains ${subdomain}.$root_domain"
|
||||||
|
domain_count=$(( domain_count + 1 ))
|
||||||
|
subdomain=$(get_element $domain_count " " $domain_list)
|
||||||
|
done
|
||||||
|
|
||||||
|
local rng_number=$(rng)
|
||||||
|
local server_var="
|
||||||
|
server {
|
||||||
|
listen 8443 ssl;
|
||||||
|
|
||||||
|
# prevent redirecting to 8080 port
|
||||||
|
# (e.g. when trailing slash is missed)
|
||||||
|
port_in_redirect off;
|
||||||
|
|
||||||
|
server_name $domains;
|
||||||
|
|
||||||
|
ssl_certificate /service/ssl/$root_domain/fullchain.pem;
|
||||||
|
ssl_certificate_key /service/ssl/$root_domain/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# allow for upstream to be offline by setting
|
||||||
|
# docker dns resolver and a variable for the server
|
||||||
|
resolver 127.0.0.11 valid=30s;
|
||||||
|
set \$web_$rng_number $server;
|
||||||
|
proxy_pass http://\$web_$rng_number:8080;
|
||||||
|
|
||||||
|
proxy_redirect off;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"
|
||||||
|
echo "$server_var"
|
||||||
|
}
|
||||||
|
|
||||||
|
function server_config()
|
||||||
|
{
|
||||||
|
local server_number=$1; shift
|
||||||
|
local server_name=$(get_element $(( server_number-1 )) " " $SERVER)
|
||||||
|
local server_domain=$@
|
||||||
|
if [ ${#server_name} -eq 0 ]; then
|
||||||
|
log server_config "no name for server name for domains [$server_domain]"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
log server_config "creating config for [$server_name] with domains [$server_domain]"
|
||||||
|
server_configs="$server_configs$(gen_server_config $server_name $server_domain)"
|
||||||
|
}
|
||||||
|
|
||||||
function cert_exists()
|
function cert_exists()
|
||||||
{
|
{
|
||||||
local domain=$1
|
local domain=$2
|
||||||
local cert_path="$cert_root_path/$domain"
|
local cert_path="$cert_root_path/$domain"
|
||||||
[ -f "$cert_path/fullchain.pem" ]
|
[ -f "$cert_path/fullchain.pem" ]
|
||||||
}
|
}
|
||||||
@@ -143,6 +233,13 @@ function nginx_handler()
|
|||||||
# start the daemon (it forks itself)
|
# start the daemon (it forks itself)
|
||||||
certs_daemon
|
certs_daemon
|
||||||
|
|
||||||
|
# generate server config
|
||||||
|
read_file server_config "$domain_file"
|
||||||
|
tmp_file="$temp_path/tmp.conf"
|
||||||
|
echo -e "$server_configs" > $tmp_file
|
||||||
|
awk 'NR==FNR { a[n++]=$0; next } /#<SERVER>/ { for (i=0;i<n;++i) print a[i]; next }1' \
|
||||||
|
$tmp_file /etc/nginx/nginx.conf > "$config_file"
|
||||||
|
|
||||||
# wait for certs to exist before starting nginx
|
# wait for certs to exist before starting nginx
|
||||||
# just have nginx crash after n retries (default 10)
|
# just have nginx crash after n retries (default 10)
|
||||||
while ! read_file cert_exists "$domain_file" && [ "$retries" -lt "$server_retries" ]; do
|
while ! read_file cert_exists "$domain_file" && [ "$retries" -lt "$server_retries" ]; do
|
||||||
@@ -153,7 +250,7 @@ function nginx_handler()
|
|||||||
|
|
||||||
# starting nginx in foreground
|
# starting nginx in foreground
|
||||||
log nginx_handler "Starting nginx in foreground"
|
log nginx_handler "Starting nginx in foreground"
|
||||||
exec nginx -g "daemon off;"
|
exec nginx -c "$config_file" -g "daemon off;"
|
||||||
}
|
}
|
||||||
|
|
||||||
function main()
|
function main()
|
||||||
|
|||||||
@@ -38,31 +38,8 @@ http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
# the following variable is automatically populated via entrypoint.sh
|
||||||
listen 8443 ssl;
|
#<SERVER>
|
||||||
|
|
||||||
# prevent redirecting to 8080 port
|
|
||||||
# (e.g. when trailing slash is missed)
|
|
||||||
port_in_redirect off;
|
|
||||||
|
|
||||||
server_name example.com www.example.com localhost;
|
|
||||||
|
|
||||||
ssl_certificate /service/ssl/example.com/fullchain.pem;
|
|
||||||
ssl_certificate_key /service/ssl/example.com/privkey.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
# allow for upstream to be offline by setting
|
|
||||||
# docker dns resolver and a variable for the server
|
|
||||||
resolver 127.0.0.11 valid=30s;
|
|
||||||
set $kweb kweb;
|
|
||||||
proxy_pass http://$kweb:8080;
|
|
||||||
|
|
||||||
proxy_redirect off;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user