forked from ss/sovereign-stack
Multilanguage ghost and other updates.
This commit is contained in:
parent
8d0af43339
commit
5a9c27c54f
1
NOTES
Normal file
1
NOTES
Normal file
@ -0,0 +1 @@
|
|||||||
|
Trezor MUST Use the "Crypto" firmware with shitcoin support in order for 2FA (WEBAUTHN) to work. Bummer.
|
14
defaults.sh
14
defaults.sh
@ -73,8 +73,7 @@ export VLAN_INTERFACE=
|
|||||||
export VM_NAME="sovereign-stack-base"
|
export VM_NAME="sovereign-stack-base"
|
||||||
export DEV_MEMORY_MB="4096"
|
export DEV_MEMORY_MB="4096"
|
||||||
export DEV_CPU_COUNT="4"
|
export DEV_CPU_COUNT="4"
|
||||||
export SSHFS_PATH="/tmp/sshfs_temp"
|
|
||||||
mkdir -p "$SSHFS_PATH"
|
|
||||||
export DOCKER_IMAGE_CACHE_FQDN="registry-1.docker.io"
|
export DOCKER_IMAGE_CACHE_FQDN="registry-1.docker.io"
|
||||||
|
|
||||||
export NEXTCLOUD_SPACE_GB=10
|
export NEXTCLOUD_SPACE_GB=10
|
||||||
@ -92,7 +91,7 @@ export NEXTCLOUD_SPACE_GB=10
|
|||||||
# exit 1
|
# exit 1
|
||||||
# fi
|
# fi
|
||||||
|
|
||||||
ENABLE_NGINX_CACHING=false
|
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
@ -105,16 +104,17 @@ BTC_CHAIN=regtest
|
|||||||
|
|
||||||
export BTC_CHAIN="$BTC_CHAIN"
|
export BTC_CHAIN="$BTC_CHAIN"
|
||||||
|
|
||||||
DEFAULT_DB_IMAGE="mariadb:10.8.3-jammy"
|
DEFAULT_DB_IMAGE="mariadb:10.9.3-jammy"
|
||||||
export ENABLE_NGINX_CACHING="$ENABLE_NGINX_CACHING"
|
|
||||||
|
|
||||||
# run the docker stack.
|
# run the docker stack.
|
||||||
export GHOST_IMAGE="ghost:5.12.3"
|
export GHOST_IMAGE="ghost:5.14.2"
|
||||||
export GHOST_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
export GHOST_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
||||||
export NGINX_IMAGE="nginx:1.23.1"
|
export NGINX_IMAGE="nginx:1.23.1"
|
||||||
export NEXTCLOUD_IMAGE="nextcloud:24.0.4"
|
export NEXTCLOUD_IMAGE="nextcloud:24.0.5"
|
||||||
export NEXTCLOUD_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
export NEXTCLOUD_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
||||||
|
|
||||||
|
# TODO PIN the gitea version number.
|
||||||
export GITEA_IMAGE="gitea/gitea:latest"
|
export GITEA_IMAGE="gitea/gitea:latest"
|
||||||
export GITEA_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
export GITEA_DB_IMAGE="$DEFAULT_DB_IMAGE"
|
||||||
|
|
||||||
|
48
deploy.sh
48
deploy.sh
@ -27,12 +27,13 @@ fi
|
|||||||
DOMAIN_NAME=
|
DOMAIN_NAME=
|
||||||
RESTORE_ARCHIVE=
|
RESTORE_ARCHIVE=
|
||||||
VPS_HOSTING_TARGET=lxd
|
VPS_HOSTING_TARGET=lxd
|
||||||
RUN_CERT_RENEWAL=true
|
RUN_CERT_RENEWAL=false
|
||||||
|
|
||||||
RESTORE_WWW=false
|
RESTORE_WWW=false
|
||||||
BACKUP_WWW=true
|
BACKUP_CERTS=true
|
||||||
|
BACKUP_GHOST=true
|
||||||
RESTORE_BTCPAY=false
|
RESTORE_BTCPAY=false
|
||||||
BACKUP_BTCPAY=true
|
BACKUP_BTCPAY=false
|
||||||
MIGRATE_WWW=false
|
MIGRATE_WWW=false
|
||||||
MIGRATE_BTCPAY=false
|
MIGRATE_BTCPAY=false
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ for i in "$@"; do
|
|||||||
;;
|
;;
|
||||||
--restore-www)
|
--restore-www)
|
||||||
RESTORE_WWW=true
|
RESTORE_WWW=true
|
||||||
BACKUP_WWW=false
|
BACKUP_GHOST=false
|
||||||
RUN_CERT_RENEWAL=false
|
RUN_CERT_RENEWAL=false
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@ -61,6 +62,10 @@ for i in "$@"; do
|
|||||||
BACKUP_BTCPAY=false
|
BACKUP_BTCPAY=false
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--backup-certs)
|
||||||
|
BACKUP_CERTS=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--archive=*)
|
--archive=*)
|
||||||
RESTORE_ARCHIVE="${i#*=}"
|
RESTORE_ARCHIVE="${i#*=}"
|
||||||
shift
|
shift
|
||||||
@ -81,12 +86,12 @@ for i in "$@"; do
|
|||||||
USER_SKIP_BTCPAY=true
|
USER_SKIP_BTCPAY=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-backup-www)
|
--backup-ghost)
|
||||||
BACKUP_WWW=false
|
BACKUP_GHOST=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-backup-btcpay)
|
--backup-btcpay)
|
||||||
BACKUP_BTCPAY=false
|
BACKUP_BTCPAY=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--migrate-www)
|
--migrate-www)
|
||||||
@ -99,8 +104,8 @@ for i in "$@"; do
|
|||||||
RUN_CERT_RENEWAL=false
|
RUN_CERT_RENEWAL=false
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-cert-renew)
|
--renew-certs)
|
||||||
RUN_CERT_RENEWAL=false
|
RUN_CERT_RENEWAL=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--reconfigure-btcpay)
|
--reconfigure-btcpay)
|
||||||
@ -123,7 +128,9 @@ export DOMAIN_NAME="$DOMAIN_NAME"
|
|||||||
export REGISTRY_DOCKER_IMAGE="registry:2"
|
export REGISTRY_DOCKER_IMAGE="registry:2"
|
||||||
export RESTORE_ARCHIVE="$RESTORE_ARCHIVE"
|
export RESTORE_ARCHIVE="$RESTORE_ARCHIVE"
|
||||||
export RESTORE_WWW="$RESTORE_WWW"
|
export RESTORE_WWW="$RESTORE_WWW"
|
||||||
export BACKUP_WWW="$BACKUP_WWW"
|
|
||||||
|
export BACKUP_CERTS="$BACKUP_CERTS"
|
||||||
|
export BACKUP_GHOST="$BACKUP_GHOST"
|
||||||
export RESTORE_BTCPAY="$RESTORE_BTCPAY"
|
export RESTORE_BTCPAY="$RESTORE_BTCPAY"
|
||||||
export BACKUP_BTCPAY="$RESTORE_BTCPAY"
|
export BACKUP_BTCPAY="$RESTORE_BTCPAY"
|
||||||
export MIGRATE_WWW="$MIGRATE_WWW"
|
export MIGRATE_WWW="$MIGRATE_WWW"
|
||||||
@ -252,10 +259,6 @@ function instantiate_vms {
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create the local packup path if it's not there!
|
|
||||||
BACKUP_PATH_CREATED=false
|
|
||||||
|
|
||||||
export BACKUP_PATH_CREATED="$BACKUP_PATH_CREATED"
|
|
||||||
export MAC_ADDRESS_TO_PROVISION=
|
export MAC_ADDRESS_TO_PROVISION=
|
||||||
export VPS_HOSTNAME="$VPS_HOSTNAME"
|
export VPS_HOSTNAME="$VPS_HOSTNAME"
|
||||||
export FQDN="$VPS_HOSTNAME.$DOMAIN_NAME"
|
export FQDN="$VPS_HOSTNAME.$DOMAIN_NAME"
|
||||||
@ -309,24 +312,13 @@ function instantiate_vms {
|
|||||||
export DDNS_HOST="$DDNS_HOST"
|
export DDNS_HOST="$DDNS_HOST"
|
||||||
export FQDN="$DDNS_HOST.$DOMAIN_NAME"
|
export FQDN="$DDNS_HOST.$DOMAIN_NAME"
|
||||||
export LXD_VM_NAME="${FQDN//./-}"
|
export LXD_VM_NAME="${FQDN//./-}"
|
||||||
BACKUP_TIMESTAMP="$(date +"%Y-%m")"
|
|
||||||
UNIX_BACKUP_TIMESTAMP="$(date +%s)"
|
|
||||||
export VIRTUAL_MACHINE="$VIRTUAL_MACHINE"
|
export VIRTUAL_MACHINE="$VIRTUAL_MACHINE"
|
||||||
export REMOTE_BACKUP_PATH="$REMOTE_HOME/backups/$VIRTUAL_MACHINE"
|
|
||||||
export BACKUP_TIMESTAMP="$BACKUP_TIMESTAMP"
|
|
||||||
export UNIX_BACKUP_TIMESTAMP="$UNIX_BACKUP_TIMESTAMP"
|
|
||||||
export REMOTE_CERT_DIR="$REMOTE_CERT_BASE_DIR/$FQDN"
|
export REMOTE_CERT_DIR="$REMOTE_CERT_BASE_DIR/$FQDN"
|
||||||
export REMOTE_BACKUP_PATH="$REMOTE_BACKUP_PATH"
|
|
||||||
export MAC_ADDRESS_TO_PROVISION="$MAC_ADDRESS_TO_PROVISION"
|
export MAC_ADDRESS_TO_PROVISION="$MAC_ADDRESS_TO_PROVISION"
|
||||||
LOCAL_BACKUP_PATH="$SITE_PATH/backups/$VIRTUAL_MACHINE/$BACKUP_TIMESTAMP"
|
|
||||||
export LOCAL_BACKUP_PATH="$LOCAL_BACKUP_PATH"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if [ ! -d "$LOCAL_BACKUP_PATH" ]; then
|
|
||||||
mkdir -p "$LOCAL_BACKUP_PATH"
|
|
||||||
BACKUP_PATH_CREATED=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# This next section of if statements is our sanity checking area.
|
# This next section of if statements is our sanity checking area.
|
||||||
@ -432,6 +424,7 @@ function stub_site_definition {
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
export DOMAIN_NAME="${DOMAIN_NAME}"
|
export DOMAIN_NAME="${DOMAIN_NAME}"
|
||||||
|
export SITE_LANGUAGE_CODES="en"
|
||||||
export DUPLICITY_BACKUP_PASSPHRASE="$(new_pass)"
|
export DUPLICITY_BACKUP_PASSPHRASE="$(new_pass)"
|
||||||
# AWS only
|
# AWS only
|
||||||
#export DDNS_PASSWORD=
|
#export DDNS_PASSWORD=
|
||||||
@ -478,7 +471,6 @@ export WWW_SERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED"
|
|||||||
export DEPLOY_BTCPAY_SERVER=true
|
export DEPLOY_BTCPAY_SERVER=true
|
||||||
export BTCPAYSERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED"
|
export BTCPAYSERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED"
|
||||||
# export BTC_CHAIN=mainnet
|
# export BTC_CHAIN=mainnet
|
||||||
# export ENABLE_NGINX_CACHING=true
|
|
||||||
export PRIMARY_DOMAIN="CHANGE_ME"
|
export PRIMARY_DOMAIN="CHANGE_ME"
|
||||||
export OTHER_SITES_LIST=
|
export OTHER_SITES_LIST=
|
||||||
EOL
|
EOL
|
||||||
|
@ -3,18 +3,45 @@
|
|||||||
set -eux
|
set -eux
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
|
||||||
|
#$1 should be the app path (ghost,nextcloud,gitea)
|
||||||
|
#$2 should be the domain to backup
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "ERROR: the app path was not specified."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# TODO: We are using extra space on the remote VPS at the moment for the duplicity backup files.
|
# TODO: We are using extra space on the remote VPS at the moment for the duplicity backup files.
|
||||||
# we could eliminate that and simply save duplicity backups to the management machine running the script
|
# we could eliminate that and simply save duplicity backups to the management machine running the script
|
||||||
# this could be done by using a local path and mounting it on the remote VPS.
|
# this could be done by using a local path and mounting it on the remote VPS.
|
||||||
# maybe something like https://superuser.com/questions/616182/how-to-mount-local-directory-to-remote-like-sshfs
|
# maybe something like https://superuser.com/questions/616182/how-to-mount-local-directory-to-remote-like-sshfs
|
||||||
|
|
||||||
|
REMOTE_BACKUP_PATH="$REMOTE_HOME/backups/www/$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
REMOTE_BACKUP_LOCATION="$REMOTE_BACKUP_PATH/$1/$DOMAIN_NAME"
|
||||||
|
|
||||||
# step 1: run duplicity on the remote system to backup all files to the remote system.
|
# step 1: run duplicity on the remote system to backup all files to the remote system.
|
||||||
ssh "$PRIMARY_WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --allow-source-mismatch --exclude "$REMOTE_HOME/backups" "$REMOTE_HOME" "file://$REMOTE_BACKUP_PATH"
|
# --allow-source-mismatch
|
||||||
ssh "$PRIMARY_WWW_FQDN" sudo chown -R ubuntu:ubuntu "$REMOTE_BACKUP_PATH"
|
ssh "$PRIMARY_WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity "$REMOTE_HOME/$1/$DOMAIN_NAME" "file://$REMOTE_BACKUP_LOCATION"
|
||||||
|
ssh "$PRIMARY_WWW_FQDN" sudo chown -R ubuntu:ubuntu "$REMOTE_BACKUP_LOCATION"
|
||||||
|
|
||||||
|
|
||||||
|
SSHFS_PATH="/tmp/sshfs_temp"
|
||||||
|
mkdir -p "$SSHFS_PATH"
|
||||||
|
|
||||||
# now let's pull down the latest files from the backup directory.
|
# now let's pull down the latest files from the backup directory.
|
||||||
# create a temp directory to serve as the mountpoint for the remote machine backups directory
|
# create a temp directory to serve as the mountpoint for the remote machine backups directory
|
||||||
sshfs "$PRIMARY_WWW_FQDN:$REMOTE_BACKUP_PATH" "$SSHFS_PATH"
|
sshfs "$PRIMARY_WWW_FQDN:$REMOTE_BACKUP_LOCATION" "$SSHFS_PATH"
|
||||||
|
|
||||||
|
# ensure our local backup path exists so we can pull down the duplicity archive to the management machine.
|
||||||
|
LOCAL_BACKUP_PATH="$SITE_PATH/backups/www/$BACKUP_TIMESTAMP"
|
||||||
|
if [ "$1" = letsencrypt ]; then
|
||||||
|
LOCAL_BACKUP_PATH="$SITE_PATH/backups/www/letsencrypt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$LOCAL_BACKUP_PATH" ]; then
|
||||||
|
mkdir -p "$LOCAL_BACKUP_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
# rsync the files from the remote server to our local backup path.
|
# rsync the files from the remote server to our local backup path.
|
||||||
rsync -av "$SSHFS_PATH/" "$LOCAL_BACKUP_PATH/"
|
rsync -av "$SSHFS_PATH/" "$LOCAL_BACKUP_PATH/"
|
||||||
@ -22,3 +49,4 @@ rsync -av "$SSHFS_PATH/" "$LOCAL_BACKUP_PATH/"
|
|||||||
# step 4: unmount the SSHFS filesystem and cleanup.
|
# step 4: unmount the SSHFS filesystem and cleanup.
|
||||||
umount "$SSHFS_PATH"
|
umount "$SSHFS_PATH"
|
||||||
rm -rf "$SSHFS_PATH"
|
rm -rf "$SSHFS_PATH"
|
||||||
|
|
@ -54,5 +54,6 @@ elif [ "$VPS_HOSTING_TARGET" = lxd ]; then
|
|||||||
-v "$REMOTE_HOME/letsencrypt/$DOMAIN_NAME/_logs":/var/log/letsencrypt \
|
-v "$REMOTE_HOME/letsencrypt/$DOMAIN_NAME/_logs":/var/log/letsencrypt \
|
||||||
certbot/certbot certonly -v --noninteractive --agree-tos --key-type ecdsa --standalone --expand -d "$DOMAIN_NAME" -d "$WWW_FQDN" -d "$BTCPAY_USER_FQDN" -d "$NEXTCLOUD_FQDN" -d "$GITEA_FQDN" -d "$NOSTR_FQDN" --email "$CERTIFICATE_EMAIL_ADDRESS"
|
certbot/certbot certonly -v --noninteractive --agree-tos --key-type ecdsa --standalone --expand -d "$DOMAIN_NAME" -d "$WWW_FQDN" -d "$BTCPAY_USER_FQDN" -d "$NEXTCLOUD_FQDN" -d "$GITEA_FQDN" -d "$NOSTR_FQDN" --email "$CERTIFICATE_EMAIL_ADDRESS"
|
||||||
|
|
||||||
|
sleep 3
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
@ -4,7 +4,7 @@ set -exu
|
|||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
# Create the nginx config file which covers all domains.
|
# Create the nginx config file which covers all domains.
|
||||||
bash -c ./stub_nginxconf.sh
|
bash -c ./stub/nginx_config.sh
|
||||||
|
|
||||||
# redirect all docker commands to the remote host.
|
# redirect all docker commands to the remote host.
|
||||||
export DOCKER_HOST="ssh://ubuntu@$PRIMARY_WWW_FQDN"
|
export DOCKER_HOST="ssh://ubuntu@$PRIMARY_WWW_FQDN"
|
||||||
@ -97,26 +97,12 @@ for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
|||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
### The next series of commands
|
./stop_docker_stacks.sh
|
||||||
# stop services.
|
|
||||||
if docker stack list --format "{{.Name}}" | grep -q webstack; then
|
|
||||||
docker stack rm webstack
|
|
||||||
sleep 15
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$BACKUP_WWW" = true ]; then
|
|
||||||
./backup.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$RESTORE_WWW" = true ]; then
|
if [ "$RESTORE_WWW" = true ]; then
|
||||||
# Generally speaking we try to restore data. But if the BACKUP directory was
|
# Generally speaking we try to restore data. But if the BACKUP directory was
|
||||||
# just created, we know that we'll deploy fresh.
|
# just created, we know that we'll deploy fresh.
|
||||||
./restore.sh
|
./restore.sh
|
||||||
else
|
|
||||||
|
|
||||||
if [ "$RUN_CERT_RENEWAL" = true ]; then
|
|
||||||
./generate_certs.sh
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@ -145,7 +131,8 @@ if [ "$DEPLOY_ONION_SITE" = true ]; then
|
|||||||
# fi
|
# fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
bash -c ./stub_docker_yml.sh
|
bash -c ./stub/nginx_yml.sh
|
||||||
|
bash -c ./stub/ghost_yml.sh
|
||||||
|
|
||||||
# # start a browser session; point it to port 80 to ensure HTTPS redirect.
|
# # start a browser session; point it to port 80 to ensure HTTPS redirect.
|
||||||
# wait-for-it -t 320 "$PRIMARY_WWW_FQDN:80"
|
# wait-for-it -t 320 "$PRIMARY_WWW_FQDN:80"
|
||||||
|
61
deployment/www/stop_docker_stacks.sh
Executable file
61
deployment/www/stop_docker_stacks.sh
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -exu
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# bring down ghost instances.
|
||||||
|
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
||||||
|
export DOMAIN_NAME="$DOMAIN_NAME"
|
||||||
|
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
||||||
|
|
||||||
|
# source the site path so we know what features it has.
|
||||||
|
source ../../reset_env.sh
|
||||||
|
source "$SITE_PATH/site_definition"
|
||||||
|
source ../../domain_env.sh
|
||||||
|
|
||||||
|
### Stop all services.
|
||||||
|
for APP in ghost; do
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
STACK_NAME="$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
if docker stack list --format "{{.Name}}" | grep -q "$STACK_NAME"; then
|
||||||
|
docker stack rm "$STACK_NAME"
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BACKUP_GHOST" = true ]; then
|
||||||
|
./backup_path.sh "$APP"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if docker stack list --format "{{.Name}}" | grep -q reverse-proxy; then
|
||||||
|
docker stack rm reverse-proxy
|
||||||
|
|
||||||
|
# wait for all docker containers to stop.
|
||||||
|
# TODO see if there's a way to check for this.
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
|
||||||
|
# generate the certs and grab a backup
|
||||||
|
if [ "$RUN_CERT_RENEWAL" = true ]; then
|
||||||
|
./generate_certs.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BACKUP_CERTS" = true ]; then
|
||||||
|
# Back each domain's certificates under /home/ubuntu/letsencrypt/domain
|
||||||
|
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
||||||
|
export DOMAIN_NAME="$DOMAIN_NAME"
|
||||||
|
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
||||||
|
|
||||||
|
# source the site path so we know what features it has.
|
||||||
|
source ../../reset_env.sh
|
||||||
|
source "$SITE_PATH/site_definition"
|
||||||
|
source ../../domain_env.sh
|
||||||
|
|
||||||
|
./backup_path.sh "letsencrypt"
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
102
deployment/www/stub/ghost_yml.sh
Executable file
102
deployment/www/stub/ghost_yml.sh
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
domain_number=0
|
||||||
|
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
||||||
|
export DOMAIN_NAME="$DOMAIN_NAME"
|
||||||
|
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
||||||
|
|
||||||
|
|
||||||
|
# source the site path so we know what features it has.
|
||||||
|
source ../../reset_env.sh
|
||||||
|
source "$SITE_PATH/site_definition"
|
||||||
|
source ../../domain_env.sh
|
||||||
|
|
||||||
|
# for each language specified in the site_definition, we spawn a separate ghost container
|
||||||
|
# at https://www.domain.com/$LANGUAGE_CODE
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
STACK_NAME="$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
|
||||||
|
# ensure directories on remote host exist so we can mount them into the containers.
|
||||||
|
ssh "$PRIMARY_WWW_FQDN" mkdir -p "$REMOTE_HOME/ghost/$DOMAIN_NAME/$LANGUAGE_CODE/ghost" "$REMOTE_HOME/ghost/$DOMAIN_NAME/$LANGUAGE_CODE/db"
|
||||||
|
|
||||||
|
export GHOST_STACK_TAG="ghost-$STACK_NAME"
|
||||||
|
export GHOST_DB_STACK_TAG="ghostdb-$STACK_NAME"
|
||||||
|
|
||||||
|
# todo append domain number or port number.
|
||||||
|
WEBSTACK_PATH="$SITE_PATH/webstack"
|
||||||
|
mkdir -p "$WEBSTACK_PATH"
|
||||||
|
export DOCKER_YAML_PATH="$WEBSTACK_PATH/ghost-$LANGUAGE_CODE.yml"
|
||||||
|
|
||||||
|
# here's the NGINX config. We support ghost and nextcloud.
|
||||||
|
echo "" > "$DOCKER_YAML_PATH"
|
||||||
|
cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
|
||||||
|
EOL
|
||||||
|
# This is the ghost for HTTPS (not over Tor)
|
||||||
|
cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
|
${GHOST_STACK_TAG}:
|
||||||
|
image: ${GHOST_IMAGE}
|
||||||
|
networks:
|
||||||
|
- ghostnet-${DOCKER_STACK_SUFFIX}-${LANGUAGE_CODE}
|
||||||
|
- ghostdbnet-${DOCKER_STACK_SUFFIX}-${LANGUAGE_CODE}
|
||||||
|
volumes:
|
||||||
|
- ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/${LANGUAGE_CODE}/ghost:/var/lib/ghost/content
|
||||||
|
environment:
|
||||||
|
EOL
|
||||||
|
|
||||||
|
cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
|
- url=https://${WWW_FQDN}/${LANGUAGE_CODE}
|
||||||
|
- database__client=mysql
|
||||||
|
- database__connection__host=${GHOST_DB_STACK_TAG}
|
||||||
|
- database__connection__user=ghost
|
||||||
|
- database__connection__password=\${GHOST_MYSQL_PASSWORD}
|
||||||
|
- database__connection__database=ghost
|
||||||
|
- database__pool__min=0
|
||||||
|
- privacy__useStructuredData=true
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
|
||||||
|
${GHOST_DB_STACK_TAG}:
|
||||||
|
image: ${GHOST_DB_IMAGE}
|
||||||
|
networks:
|
||||||
|
- ghostdbnet-${DOCKER_STACK_SUFFIX}-${LANGUAGE_CODE}
|
||||||
|
volumes:
|
||||||
|
- ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/${LANGUAGE_CODE}/db:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=\${GHOST_MYSQL_ROOT_PASSWORD}
|
||||||
|
- MYSQL_DATABASE=ghost
|
||||||
|
- MYSQL_USER=ghost
|
||||||
|
- MYSQL_PASSWORD=\${GHOST_MYSQL_PASSWORD}
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
|
networks:
|
||||||
|
EOL
|
||||||
|
|
||||||
|
if [ "$DEPLOY_GHOST" = true ]; then
|
||||||
|
GHOSTNET_NAME="ghostnet-$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
GHOSTDBNET_NAME="ghostdbnet-$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
|
||||||
|
cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
|
${GHOSTNET_NAME}:
|
||||||
|
name: "reverse-proxy_ghostnet-$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
external: true
|
||||||
|
|
||||||
|
${GHOSTDBNET_NAME}:
|
||||||
|
EOL
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker stack deploy -c "$DOCKER_YAML_PATH" "$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
domain_number=$((domain_number+1))
|
||||||
|
done
|
27
deployment/www/stub/gittea_yml.sh
Normal file
27
deployment/www/stub/gittea_yml.sh
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$DEPLOY_GITEA" = true ]; then
|
||||||
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# TLS listener for ${GITEA_FQDN}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
server_name ${GITEA_FQDN};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_headers_hash_max_size 512;
|
||||||
|
proxy_headers_hash_bucket_size 64;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
proxy_set_header X-NginX-Proxy true;
|
||||||
|
|
||||||
|
proxy_pass http://gitea:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOL
|
||||||
|
fi
|
44
deployment/www/stub/nextcloud_yml.sh
Normal file
44
deployment/www/stub/nextcloud_yml.sh
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
||||||
|
# cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# # TLS listener for ${NEXTCLOUD_FQDN}
|
||||||
|
# server {
|
||||||
|
# listen 443 ssl http2;
|
||||||
|
# listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
# ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
||||||
|
# ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
|
||||||
|
# ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
||||||
|
|
||||||
|
# server_name ${NEXTCLOUD_FQDN};
|
||||||
|
|
||||||
|
# location / {
|
||||||
|
# proxy_headers_hash_max_size 512;
|
||||||
|
# proxy_headers_hash_bucket_size 64;
|
||||||
|
# proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
# proxy_set_header Host \$host;
|
||||||
|
# proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
# proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
# proxy_set_header X-NginX-Proxy true;
|
||||||
|
|
||||||
|
# proxy_pass http://nextcloud:80;
|
||||||
|
# }
|
||||||
|
|
||||||
|
# # https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html
|
||||||
|
# location /.well-known/carddav {
|
||||||
|
# return 301 \$scheme://\$host/remote.php/dav;
|
||||||
|
# }
|
||||||
|
|
||||||
|
# location /.well-known/caldav {
|
||||||
|
# return 301 \$scheme://\$host/remote.php/dav;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# EOL
|
||||||
|
|
||||||
|
# fi
|
||||||
|
|
@ -20,9 +20,9 @@ for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
|||||||
export CONTAINER_TLS_PATH="/etc/letsencrypt/${DOMAIN_NAME}/live/${DOMAIN_NAME}"
|
export CONTAINER_TLS_PATH="/etc/letsencrypt/${DOMAIN_NAME}/live/${DOMAIN_NAME}"
|
||||||
|
|
||||||
# source the site path so we know what features it has.
|
# source the site path so we know what features it has.
|
||||||
source ../../reset_env.sh
|
source ../../../reset_env.sh
|
||||||
source "$SITE_PATH/site_definition"
|
source "$SITE_PATH/site_definition"
|
||||||
source ../../domain_env.sh
|
source ../../../domain_env.sh
|
||||||
|
|
||||||
echo "Doing DOMAIN_NAME: $DOMAIN_NAME"
|
echo "Doing DOMAIN_NAME: $DOMAIN_NAME"
|
||||||
if [ $iteration = 0 ]; then
|
if [ $iteration = 0 ]; then
|
||||||
@ -43,7 +43,6 @@ http {
|
|||||||
proxy_busy_buffers_size 256k;
|
proxy_busy_buffers_size 256k;
|
||||||
client_header_buffer_size 500k;
|
client_header_buffer_size 500k;
|
||||||
large_client_header_buffers 4 500k;
|
large_client_header_buffers 4 500k;
|
||||||
http2_max_header_size 500k;
|
|
||||||
|
|
||||||
# Needed websocket support (used by Ledger hardware wallets)
|
# Needed websocket support (used by Ledger hardware wallets)
|
||||||
map \$http_upgrade \$connection_upgrade {
|
map \$http_upgrade \$connection_upgrade {
|
||||||
@ -167,6 +166,15 @@ EOL
|
|||||||
#map \$http_user_agent \$og_prefix {
|
#map \$http_user_agent \$og_prefix {
|
||||||
# ~*(googlebot|twitterbot)/ /open-graph;
|
# ~*(googlebot|twitterbot)/ /open-graph;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
# this map allows us to route the clients request to the correct Ghost instance
|
||||||
|
# based on the clients browser language setting.
|
||||||
|
map \$http_accept_language \$lang {
|
||||||
|
default "en";
|
||||||
|
~en en;
|
||||||
|
~es es;
|
||||||
|
}
|
||||||
|
|
||||||
EOL
|
EOL
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -184,7 +192,7 @@ EOL
|
|||||||
|
|
||||||
# catch all; send request to ${WWW_FQDN}
|
# catch all; send request to ${WWW_FQDN}
|
||||||
location / {
|
location / {
|
||||||
return 301 https://${WWW_FQDN}\$request_uri;
|
return 301 https://${WWW_FQDN}/\$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOL
|
EOL
|
||||||
@ -209,17 +217,9 @@ EOL
|
|||||||
|
|
||||||
#access_log /var/log/nginx/ghost-access.log;
|
#access_log /var/log/nginx/ghost-access.log;
|
||||||
#error_log /var/log/nginx/ghost-error.log;
|
#error_log /var/log/nginx/ghost-error.log;
|
||||||
|
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
|
|
||||||
if [ "$ENABLE_NGINX_CACHING" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# main TLS listener; proxies requests to ghost service. NGINX configured to cache
|
|
||||||
proxy_cache_path /tmp/nginx_ghost levels=1:2 keys_zone=ghostcache:600m max_size=100m inactive=24h;
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# SERVER block for BTCPAY Server
|
# SERVER block for BTCPAY Server
|
||||||
if [ "$VPS_HOSTING_TARGET" = lxd ]; then
|
if [ "$VPS_HOSTING_TARGET" = lxd ]; then
|
||||||
# gitea http to https redirect.
|
# gitea http to https redirect.
|
||||||
@ -229,7 +229,6 @@ EOL
|
|||||||
# http://${BTCPAY_USER_FQDN} redirect to https://${BTCPAY_USER_FQDN}
|
# http://${BTCPAY_USER_FQDN} redirect to https://${BTCPAY_USER_FQDN}
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
ssl on;
|
|
||||||
|
|
||||||
ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
||||||
ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
|
ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
|
||||||
@ -257,9 +256,19 @@ EOL
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo " # set up cache paths for nginx caching" >>"$NGINX_CONF_PATH"
|
||||||
# the open server block for the HTTPS listener
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
STACK_NAME="$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
proxy_cache_path /tmp/${STACK_NAME} levels=1:2 keys_zone=${STACK_NAME}:600m max_size=100m inactive=24h;
|
||||||
|
EOL
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# the open server block for the HTTPS listener for ghost
|
||||||
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
|
||||||
|
# Main HTTPS listener for https://${WWW_FQDN}
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
listen [::]:443 ssl http2;
|
listen [::]:443 ssl http2;
|
||||||
@ -269,41 +278,53 @@ EOL
|
|||||||
ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
||||||
|
|
||||||
server_name ${WWW_FQDN};
|
server_name ${WWW_FQDN};
|
||||||
EOL
|
|
||||||
|
|
||||||
# add the Onion-Location header if specifed.
|
|
||||||
if [ "$DEPLOY_ONION_SITE" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
add_header Onion-Location https://${ONION_ADDRESS}\$request_uri;
|
|
||||||
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ENABLE_NGINX_CACHING" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
|
|
||||||
# No cache + keep cookies for admin and previews
|
|
||||||
location ~ ^/(ghost/|p/|private/) {
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header Host \$http_host;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
proxy_pass http://ghost-${iteration}:2368;
|
|
||||||
}
|
|
||||||
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
# proxy config for ghost
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# Set the crawler policy.
|
# Set the crawler policy.
|
||||||
location = /robots.txt {
|
location = /robots.txt {
|
||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
return 200 "User-Agent: *\\nAllow: /\\n";
|
return 200 "User-Agent: *\\nAllow: /\\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
# # add the Onion-Location header if specifed.
|
||||||
|
# if [ "$DEPLOY_ONION_SITE" = true ]; then
|
||||||
|
# cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# add_header Onion-Location https://${ONION_ADDRESS}\$request_uri;
|
||||||
|
|
||||||
|
# EOL
|
||||||
|
# fi
|
||||||
|
|
||||||
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# if the client is accesssing https://${WWW_FQDN}/ , then we check the client
|
||||||
|
# langauge header and send them to the correct ghost instance based on language
|
||||||
location / {
|
location / {
|
||||||
|
rewrite (.*) \$1/\$lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
STACK_NAME="$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE"
|
||||||
|
|
||||||
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
location ~ ^/${LANGUAGE_CODE}/(ghost/|p/|private/) {
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header Host \$http_host;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
proxy_pass http://ghost-${STACK_NAME}:2368;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# Location block to back https://${WWW_FQDN}/${LANGUAGE_CODE}
|
||||||
|
location /${LANGUAGE_CODE} {
|
||||||
#set_from_accept_language \$lang en es;
|
#set_from_accept_language \$lang en es;
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
proxy_set_header Host \$http_host;
|
proxy_set_header Host \$http_host;
|
||||||
@ -311,11 +332,8 @@ fi
|
|||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
proxy_intercept_errors on;
|
proxy_intercept_errors on;
|
||||||
proxy_pass http://ghost-${iteration}:2368;
|
proxy_pass http://ghost-${DOCKER_STACK_SUFFIX}-${LANGUAGE_CODE}:2368;
|
||||||
EOL
|
|
||||||
|
|
||||||
if [ "$ENABLE_NGINX_CACHING" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# https://stanislas.blog/2019/08/ghost-nginx-cache/ for nginx caching instructions
|
# https://stanislas.blog/2019/08/ghost-nginx-cache/ for nginx caching instructions
|
||||||
# Remove cookies which are useless for anonymous visitor and prevent caching
|
# Remove cookies which are useless for anonymous visitor and prevent caching
|
||||||
proxy_ignore_headers Set-Cookie Cache-Control;
|
proxy_ignore_headers Set-Cookie Cache-Control;
|
||||||
@ -323,7 +341,7 @@ EOL
|
|||||||
|
|
||||||
# Add header for cache status (miss or hit)
|
# Add header for cache status (miss or hit)
|
||||||
add_header X-Cache-Status \$upstream_cache_status;
|
add_header X-Cache-Status \$upstream_cache_status;
|
||||||
proxy_cache ghostcache;
|
proxy_cache ${DOCKER_STACK_SUFFIX}-${LANGUAGE_CODE};
|
||||||
|
|
||||||
# Default TTL: 1 day
|
# Default TTL: 1 day
|
||||||
proxy_cache_valid 5s;
|
proxy_cache_valid 5s;
|
||||||
@ -341,16 +359,12 @@ EOL
|
|||||||
|
|
||||||
# Bypass cache for errors
|
# Bypass cache for errors
|
||||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||||
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
# this is the closing location / block for the ghost HTTPS segment
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
# TODO this MIGHT be part of the solution for Twitter Cards.
|
# TODO this MIGHT be part of the solution for Twitter Cards.
|
||||||
# location /contents {
|
# location /contents {
|
||||||
# resolver 127.0.0.11 ipv6=off valid=5m;
|
# resolver 127.0.0.11 ipv6=off valid=5m;
|
||||||
@ -359,102 +373,16 @@ EOL
|
|||||||
# proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
# proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
# proxy_set_header X-Forwarded-Proto \$scheme;
|
# proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
# proxy_intercept_errors on;
|
# proxy_intercept_errors on;
|
||||||
# proxy_pass http://ghost-${iteration}::2368\$og_prefix\$request_uri;
|
# proxy_pass http://ghost-${DOCKER_STACK_SUFFIX}-${SITE_LANGUAGE_CODES}::2368\$og_prefix\$request_uri;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# this is the closing server block for the ghost HTTPS segment
|
# this is the closing server block for the ghost HTTPS segment
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
# tor config
|
|
||||||
if [ "$DEPLOY_ONION_SITE" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# server listener for tor v3 onion endpoint
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
server_name ${ONION_ADDRESS};
|
|
||||||
#access_log /var/log/nginx/tor-www.log;
|
|
||||||
|
|
||||||
# administration not allowed over tor interface.
|
|
||||||
location /ghost { deny all; }
|
|
||||||
location / {
|
|
||||||
proxy_set_header X-Forwarded-For 1.1.1.1;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Real-IP 1.1.1.1;
|
|
||||||
proxy_set_header Host \$http_host;
|
|
||||||
proxy_pass http://tor-ghost:2368;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# TLS listener for ${NEXTCLOUD_FQDN}
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
|
||||||
ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
|
|
||||||
ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
|
|
||||||
|
|
||||||
server_name ${NEXTCLOUD_FQDN};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_headers_hash_max_size 512;
|
|
||||||
proxy_headers_hash_bucket_size 64;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
proxy_set_header X-NginX-Proxy true;
|
|
||||||
|
|
||||||
proxy_pass http://nextcloud:80;
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html
|
|
||||||
location /.well-known/carddav {
|
|
||||||
return 301 \$scheme://\$host/remote.php/dav;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /.well-known/caldav {
|
|
||||||
return 301 \$scheme://\$host/remote.php/dav;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOL
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [ "$DEPLOY_GITEA" = true ]; then
|
|
||||||
cat >>"$NGINX_CONF_PATH" <<EOL
|
|
||||||
# TLS listener for ${GITEA_FQDN}
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name ${GITEA_FQDN};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_headers_hash_max_size 512;
|
|
||||||
proxy_headers_hash_bucket_size 64;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
proxy_set_header X-NginX-Proxy true;
|
|
||||||
|
|
||||||
proxy_pass http://gitea:3000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
iteration=$((iteration+1))
|
iteration=$((iteration+1))
|
||||||
done
|
done
|
||||||
|
|
88
deployment/www/stub/nginx_yml.sh
Executable file
88
deployment/www/stub/nginx_yml.sh
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
#https://github.com/fiatjaf/expensive-relay
|
||||||
|
# NOSTR RELAY WHICH REQUIRES PAYMENTS.
|
||||||
|
DOCKER_YAML_PATH="$PROJECT_PATH/nginx.yml"
|
||||||
|
cat > "$DOCKER_YAML_PATH" <<EOL
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: ${NGINX_IMAGE}
|
||||||
|
ports:
|
||||||
|
- 0.0.0.0:443:443
|
||||||
|
- 0.0.0.0:80:80
|
||||||
|
networks:
|
||||||
|
EOL
|
||||||
|
|
||||||
|
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
||||||
|
export DOMAIN_NAME="$DOMAIN_NAME"
|
||||||
|
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
||||||
|
|
||||||
|
# source the site path so we know what features it has.
|
||||||
|
source ../../../reset_env.sh
|
||||||
|
source "$SITE_PATH/site_definition"
|
||||||
|
source ../../../domain_env.sh
|
||||||
|
|
||||||
|
# for each language specified in the site_definition, we spawn a separate ghost container
|
||||||
|
# at https://www.domain.com/$LANGUAGE_CODE
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
|
||||||
|
cat >> "$DOCKER_YAML_PATH" <<EOL
|
||||||
|
- ghostnet-$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE
|
||||||
|
EOL
|
||||||
|
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
cat >> "$DOCKER_YAML_PATH" <<EOL
|
||||||
|
volumes:
|
||||||
|
- ${REMOTE_HOME}/letsencrypt:/etc/letsencrypt:ro
|
||||||
|
configs:
|
||||||
|
- source: nginx-config
|
||||||
|
target: /etc/nginx/nginx.conf
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
|
||||||
|
configs:
|
||||||
|
nginx-config:
|
||||||
|
file: ${PROJECT_PATH}/nginx.conf
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################ NETWORKS SECTION
|
||||||
|
|
||||||
|
cat >> "$DOCKER_YAML_PATH" <<EOL
|
||||||
|
networks:
|
||||||
|
EOL
|
||||||
|
|
||||||
|
|
||||||
|
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
||||||
|
export DOMAIN_NAME="$DOMAIN_NAME"
|
||||||
|
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
||||||
|
|
||||||
|
# source the site path so we know what features it has.
|
||||||
|
source ../../../reset_env.sh
|
||||||
|
source "$SITE_PATH/site_definition"
|
||||||
|
source ../../../domain_env.sh
|
||||||
|
|
||||||
|
# for each language specified in the site_definition, we spawn a separate ghost container
|
||||||
|
# at https://www.domain.com/$LANGUAGE_CODE
|
||||||
|
for LANGUAGE_CODE in ${SITE_LANGUAGE_CODES//,/ }; do
|
||||||
|
cat >> "$DOCKER_YAML_PATH" <<EOL
|
||||||
|
ghostnet-$DOCKER_STACK_SUFFIX-$LANGUAGE_CODE:
|
||||||
|
attachable: true
|
||||||
|
|
||||||
|
EOL
|
||||||
|
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
docker stack deploy -c "$DOCKER_YAML_PATH" "reverse-proxy"
|
||||||
|
# iterate over all our domains and create the nginx config file.
|
23
deployment/www/stub/tor_onions.sh
Normal file
23
deployment/www/stub/tor_onions.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
# # tor config
|
||||||
|
# if [ "$DEPLOY_ONION_SITE" = true ]; then
|
||||||
|
# cat >>"$NGINX_CONF_PATH" <<EOL
|
||||||
|
# # server listener for tor v3 onion endpoint
|
||||||
|
# server {
|
||||||
|
# listen 443 ssl http2;
|
||||||
|
# listen [::]:443 ssl http2;
|
||||||
|
# server_name ${ONION_ADDRESS};
|
||||||
|
# #access_log /var/log/nginx/tor-www.log;
|
||||||
|
|
||||||
|
# # administration not allowed over tor interface.
|
||||||
|
# location /ghost { deny all; }
|
||||||
|
# location / {
|
||||||
|
# proxy_set_header X-Forwarded-For 1.1.1.1;
|
||||||
|
# proxy_set_header X-Forwarded-Proto https;
|
||||||
|
# proxy_set_header X-Real-IP 1.1.1.1;
|
||||||
|
# proxy_set_header Host \$http_host;
|
||||||
|
# proxy_pass http://tor-ghost:2368;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# EOL
|
||||||
|
# fi
|
@ -1,144 +1,9 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ssh "$PRIMARY_WWW_FQDN" sudo rm -rf /home/ubuntu/ghost
|
|
||||||
sleep 4
|
|
||||||
|
|
||||||
|
|
||||||
#https://github.com/fiatjaf/expensive-relay
|
|
||||||
# NOSTR RELAY WHICH REQUIRES PAYMENTS.
|
|
||||||
DOCKER_YAML_PATH="$PROJECT_PATH/nginx.yml"
|
|
||||||
cat > "$DOCKER_YAML_PATH" <<EOL
|
|
||||||
version: "3.8"
|
|
||||||
services:
|
|
||||||
|
|
||||||
nginx:
|
|
||||||
image: ${NGINX_IMAGE}
|
|
||||||
ports:
|
|
||||||
- 0.0.0.0:443:443
|
|
||||||
- 0.0.0.0:80:80
|
|
||||||
networks:
|
|
||||||
EOL
|
|
||||||
|
|
||||||
for i in $(seq 0 $DOMAIN_COUNT); do
|
|
||||||
cat >> "$DOCKER_YAML_PATH" <<EOL
|
|
||||||
- ghostnet-$i
|
|
||||||
EOL
|
|
||||||
done
|
|
||||||
|
|
||||||
cat >> "$DOCKER_YAML_PATH" <<EOL
|
|
||||||
volumes:
|
|
||||||
- ${REMOTE_HOME}/letsencrypt:/etc/letsencrypt:ro
|
|
||||||
configs:
|
|
||||||
- source: nginx-config
|
|
||||||
target: /etc/nginx/nginx.conf
|
|
||||||
deploy:
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
|
|
||||||
configs:
|
|
||||||
nginx-config:
|
|
||||||
file: ${PROJECT_PATH}/nginx.conf
|
|
||||||
|
|
||||||
EOL
|
|
||||||
|
|
||||||
cat >> "$DOCKER_YAML_PATH" <<EOL
|
|
||||||
networks:
|
|
||||||
EOL
|
|
||||||
|
|
||||||
for i in $(seq 0 $DOMAIN_COUNT); do
|
|
||||||
cat >> "$DOCKER_YAML_PATH" <<EOL
|
|
||||||
ghostnet-$i:
|
|
||||||
attachable: true
|
|
||||||
|
|
||||||
EOL
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
docker stack deploy -c "$DOCKER_YAML_PATH" "reverse-proxy"
|
|
||||||
|
|
||||||
|
|
||||||
# iterate over all our domains and create the nginx config file.
|
|
||||||
|
|
||||||
|
|
||||||
domain_number=0
|
|
||||||
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
|
|
||||||
export DOMAIN_NAME="$DOMAIN_NAME"
|
|
||||||
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
|
|
||||||
|
|
||||||
ssh "$PRIMARY_WWW_FQDN" mkdir -p "$REMOTE_HOME/ghost/$DOMAIN_NAME/ghost" "$REMOTE_HOME/ghost/$DOMAIN_NAME/db"
|
|
||||||
|
|
||||||
# source the site path so we know what features it has.
|
|
||||||
source ../../reset_env.sh
|
|
||||||
source "$SITE_PATH/site_definition"
|
|
||||||
source ../../domain_env.sh
|
|
||||||
|
|
||||||
STACK_TAG="ghost-$domain_number"
|
|
||||||
|
|
||||||
# todo append domain number or port number.
|
|
||||||
mkdir -p "$SITE_PATH/webstack"
|
|
||||||
DOCKER_YAML_PATH="$SITE_PATH/webstack/$STACK_TAG.yml"
|
|
||||||
export DOCKER_YAML_PATH="$DOCKER_YAML_PATH"
|
|
||||||
# if [ "$DEPLOY_ONION_SITE" = true ]; then
|
|
||||||
# if [ -z "$ONION_ADDRESS" ]; then
|
|
||||||
# echo "ERROR: ONION_ADDRESS is not defined."
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# here's the NGINX config. We support ghost and nextcloud.
|
|
||||||
echo "" > "$DOCKER_YAML_PATH"
|
|
||||||
|
|
||||||
cat >>"$DOCKER_YAML_PATH" <<EOL
|
|
||||||
version: "3.8"
|
|
||||||
services:
|
|
||||||
|
|
||||||
EOL
|
|
||||||
|
|
||||||
|
|
||||||
# This is the ghost for HTTPS (not over Tor)
|
|
||||||
cat >>"$DOCKER_YAML_PATH" <<EOL
|
|
||||||
ghost-${domain_number}:
|
|
||||||
image: ${GHOST_IMAGE}
|
|
||||||
networks:
|
|
||||||
- ghostnet-${domain_number}
|
|
||||||
- ghostdbnet-${domain_number}
|
|
||||||
volumes:
|
|
||||||
- ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/ghost:/var/lib/ghost/content
|
|
||||||
environment:
|
|
||||||
- url=https://${PRIMARY_WWW_FQDN}
|
|
||||||
- database__client=mysql
|
|
||||||
- database__connection__host=ghostdb-${domain_number}
|
|
||||||
- database__connection__user=ghost
|
|
||||||
- database__connection__password=\${GHOST_MYSQL_PASSWORD}
|
|
||||||
- database__connection__database=ghost
|
|
||||||
- database__pool__min=0
|
|
||||||
- privacy__useStructuredData=true
|
|
||||||
deploy:
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
|
|
||||||
ghostdb-${domain_number}:
|
|
||||||
image: ${GHOST_DB_IMAGE}
|
|
||||||
networks:
|
|
||||||
- ghostdbnet-${domain_number}
|
|
||||||
volumes:
|
|
||||||
- ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/db:/var/lib/mysql
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=\${GHOST_MYSQL_ROOT_PASSWORD}
|
|
||||||
- MYSQL_DATABASE=ghost
|
|
||||||
- MYSQL_USER=ghost
|
|
||||||
- MYSQL_PASSWORD=\${GHOST_MYSQL_PASSWORD}
|
|
||||||
deploy:
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
|
|
||||||
EOL
|
|
||||||
|
|
||||||
|
|
||||||
# if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
# if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
||||||
@ -302,19 +167,7 @@ EOL
|
|||||||
# fi
|
# fi
|
||||||
# #-------------------------
|
# #-------------------------
|
||||||
|
|
||||||
# networks ----------------------
|
|
||||||
cat >>"$DOCKER_YAML_PATH" <<EOL
|
|
||||||
networks:
|
|
||||||
EOL
|
|
||||||
|
|
||||||
if [ "$DEPLOY_GHOST" = true ]; then
|
|
||||||
cat >>"$DOCKER_YAML_PATH" <<EOL
|
|
||||||
ghostnet-${domain_number}:
|
|
||||||
name: "reverse-proxy_ghostnet-${domain_number}"
|
|
||||||
external: true
|
|
||||||
ghostdbnet-${domain_number}:
|
|
||||||
EOL
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
# if [ "$DEPLOY_NEXTCLOUD" = true ]; then
|
||||||
# cat >>"$DOCKER_YAML_PATH" <<EOL
|
# cat >>"$DOCKER_YAML_PATH" <<EOL
|
||||||
@ -346,9 +199,3 @@ EOL
|
|||||||
# EOL
|
# EOL
|
||||||
# fi
|
# fi
|
||||||
# # -----------------------------
|
# # -----------------------------
|
||||||
|
|
||||||
|
|
||||||
docker stack deploy -c "$DOCKER_YAML_PATH" "$STACK_TAG"
|
|
||||||
|
|
||||||
domain_number=$((domain_number+1))
|
|
||||||
done
|
|
||||||
|
@ -16,3 +16,11 @@ export REMOTE_GITEA_PATH="$REMOTE_HOME/gitea"
|
|||||||
export BTC_CHAIN="$BTC_CHAIN"
|
export BTC_CHAIN="$BTC_CHAIN"
|
||||||
export WWW_INSTANCE_TYPE="$WWW_INSTANCE_TYPE"
|
export WWW_INSTANCE_TYPE="$WWW_INSTANCE_TYPE"
|
||||||
export BTCPAY_ADDITIONAL_HOSTNAMES="$BTCPAY_ADDITIONAL_HOSTNAMES"
|
export BTCPAY_ADDITIONAL_HOSTNAMES="$BTCPAY_ADDITIONAL_HOSTNAMES"
|
||||||
|
|
||||||
|
BACKUP_TIMESTAMP="$(date +"%Y-%m")"
|
||||||
|
UNIX_BACKUP_TIMESTAMP="$(date +%s)"
|
||||||
|
|
||||||
|
|
||||||
|
export BACKUP_TIMESTAMP="$BACKUP_TIMESTAMP"
|
||||||
|
export UNIX_BACKUP_TIMESTAMP="$UNIX_BACKUP_TIMESTAMP"
|
||||||
|
export DOCKER_STACK_SUFFIX="${DOMAIN_NAME//./-}"
|
@ -17,6 +17,8 @@ export NEXTCLOUD_MYSQL_PASSWORD=
|
|||||||
export NEXTCLOUD_MYSQL_ROOT_PASSWORD=
|
export NEXTCLOUD_MYSQL_ROOT_PASSWORD=
|
||||||
export GITEA_MYSQL_PASSWORD=
|
export GITEA_MYSQL_PASSWORD=
|
||||||
export GITEA_MYSQL_ROOT_PASSWORD=
|
export GITEA_MYSQL_ROOT_PASSWORD=
|
||||||
|
export SITE_LANGUAGE_CODES="en"
|
||||||
|
export LANGUAGE_CODE=
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
source "$SCRIPT_DIR/defaults.sh"
|
source "$SCRIPT_DIR/defaults.sh"
|
||||||
|
Loading…
Reference in New Issue
Block a user