1
1

More work on self-hosting + projects.

This commit is contained in:
Derek Smith 2022-09-09 14:00:07 -04:00
parent 07c1c13bba
commit 8d0af43339
Signed by: farscapian
GPG Key ID: 8F1CD799CCA516CC
15 changed files with 720 additions and 647 deletions

View File

@ -35,16 +35,14 @@ if [ "$COMMAND" = create ]; then
cat >"$CLUSTER_DEFINITION" <<EOL cat >"$CLUSTER_DEFINITION" <<EOL
#!/bin/bash #!/bin/bash
# Note: the path above ./ corresponds to your LXD Remote. If your remote is set to 'cluster1' # see https://www.sovereign-stack.org/cluster_definition for more info!
# Then $HOME/ss-clusters/cluster1 will be your cluster working path.
export LXD_CLUSTER_PASSWORD="$(gpg --gen-random --armor 1 14)" export LXD_CLUSTER_PASSWORD="$(gpg --gen-random --armor 1 14)"
export SOVEREIGN_STACK_MAC_ADDRESS="CHANGE_ME_REQUIRED"
export PROJECT_NAME="[public|private1|private2]" export PROJECT_NAME="$CLUSTER_NAME-public"
# only relevant
export REGISTRY_URL="http://$(hostname).$(resolvectl status | grep 'DNS Domain:' | awk '{ print $3 }'):5000" export REGISTRY_URL="http://$(hostname).$(resolvectl status | grep 'DNS Domain:' | awk '{ print $3 }'):5000"
export REGISTRY_USERNAME="" export REGISTRY_USERNAME="CHANGE_ME"
export REGISTRY_PASSWORD="" export REGISTRY_PASSWORD="CHANGE_ME"
EOL EOL
@ -89,29 +87,29 @@ EOL
esac esac
done done
if [ -z "$DATA_PLANE_MACVLAN_INTERFACE" ]; then # if [ -z "$DATA_PLANE_MACVLAN_INTERFACE" ]; then
echo "INFO: It looks like you didn't provide input on the command line for the data plane macvlan interface." # echo "INFO: It looks like you didn't provide input on the command line for the data plane macvlan interface."
echo " We need to know which interface that is! Enter it here now." # echo " We need to know which interface that is! Enter it here now."
echo "" # echo ""
ssh "ubuntu@$FQDN" ip link # ssh "ubuntu@$FQDN" ip link
echo "Please enter the network interface that's dedicated to the Sovereign Stack data plane: " # echo "Please enter the network interface that's dedicated to the Sovereign Stack data plane: "
read -r DATA_PLANE_MACVLAN_INTERFACE # read -r DATA_PLANE_MACVLAN_INTERFACE
fi # fi
if [ -z "$DISK_TO_USE" ]; then # if [ -z "$DISK_TO_USE" ]; then
echo "INFO: It looks like the DISK_TO_USE has not been set. Enter it now." # echo "INFO: It looks like the DISK_TO_USE has not been set. Enter it now."
echo "" # echo ""
ssh "ubuntu@$FQDN" lsblk # ssh "ubuntu@$FQDN" lsblk
USER_DISK= # USER_DISK=
echo "Please enter the disk or partition that Sovereign Stack will use to store data (default: loop): " # echo "Please enter the disk or partition that Sovereign Stack will use to store data (default: loop): "
read -r USER_DISK # read -r USER_DISK
fi # fi
else else
echo "ERROR: the cluster already exists! You need to go delete your lxd remote if you want to re-create your cluster." echo "ERROR: the cluster already exists! You need to go delete your lxd remote if you want to re-create your cluster."

View File

@ -14,7 +14,7 @@ export DEPLOY_GITEA=false
export WWW_HOSTNAME="www" export WWW_HOSTNAME="www"
export BTCPAY_HOSTNAME="btcpay" export BTCPAY_HOSTNAME="btcpay"
export BTCPAY_HOSTNAME_IN_CERT="pay" export BTCPAY_HOSTNAME_IN_CERT="tip"
export NEXTCLOUD_HOSTNAME="nextcloud" export NEXTCLOUD_HOSTNAME="nextcloud"
export GITEA_HOSTNAME="git" export GITEA_HOSTNAME="git"
export NOSTR_HOSTNAME="relay" export NOSTR_HOSTNAME="relay"
@ -82,8 +82,8 @@ export NEXTCLOUD_SPACE_GB=10
# first of all, if there are uncommited changes, we quit. You better stash or commit! # first of all, if there are uncommited changes, we quit. You better stash or commit!
# Remote VPS instances are tagged with your current git HEAD so we know which code revision # Remote VPS instances are tagged with your current git HEAD so we know which code revision
# used when provisioning the VPS. # used when provisioning the VPS.
LATEST_GIT_COMMIT="$(cat ./.git/refs/heads/master)" #LATEST_GIT_COMMIT="$(cat ./.git/refs/heads/master)"
export LATEST_GIT_COMMIT="$LATEST_GIT_COMMIT" #export LATEST_GIT_COMMIT="$LATEST_GIT_COMMIT"
# check if there are any uncommited changes. It's dangerous to instantiate VMs using # check if there are any uncommited changes. It's dangerous to instantiate VMs using
# code that hasn't been committed. # code that hasn't been committed.
@ -109,18 +109,18 @@ DEFAULT_DB_IMAGE="mariadb:10.8.3-jammy"
export ENABLE_NGINX_CACHING="$ENABLE_NGINX_CACHING" export ENABLE_NGINX_CACHING="$ENABLE_NGINX_CACHING"
# run the docker stack. # run the docker stack.
export GHOST_IMAGE="ghost:5.9.4" export GHOST_IMAGE="ghost:5.12.3"
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.3" export NEXTCLOUD_IMAGE="nextcloud:24.0.4"
export NEXTCLOUD_DB_IMAGE="$DEFAULT_DB_IMAGE" export NEXTCLOUD_DB_IMAGE="$DEFAULT_DB_IMAGE"
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"
export SOVEREIGN_STACK_MAC_ADDRESS= export SOVEREIGN_STACK_MAC_ADDRESS=
export WWW_MAC_ADDRESS= export WWW_SERVER_MAC_ADDRESS=
export BTCPAY_MAC_ADDRESS= export BTCPAYSERVER_MAC_ADDRESS=
export CLUSTERS_DIR="$HOME/ss-clusters" export CLUSTERS_DIR="$HOME/ss-clusters"
export PROJECTS_DIR="$HOME/ss-projects" export PROJECTS_DIR="$HOME/ss-projects"
@ -132,7 +132,7 @@ export BASE_LXC_IMAGE="ubuntu/22.04/cloud"
# Deploy a registry cache on your management machine. # Deploy a registry cache on your management machine.
export DEPLOY_MGMT_REGISTRY=true export DEPLOY_MGMT_REGISTRY=true
export OTHER_SITES_LIST=
export REMOTE_HOME="/home/ubuntu" export REMOTE_HOME="/home/ubuntu"

189
deploy.sh
View File

@ -128,6 +128,7 @@ 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"
export MIGRATE_BTCPAY="$MIGRATE_BTCPAY" export MIGRATE_BTCPAY="$MIGRATE_BTCPAY"
export RUN_CERT_RENEWAL="$RUN_CERT_RENEWAL"
if [ "$VPS_HOSTING_TARGET" = aws ]; then if [ "$VPS_HOSTING_TARGET" = aws ]; then
@ -150,8 +151,8 @@ mkdir -p "$CLUSTER_PATH"
if [ ! -f "$CLUSTER_PATH/authorized_keys" ]; then if [ ! -f "$CLUSTER_PATH/authorized_keys" ]; then
cat "$SSH_HOME/id_rsa.pub" >> "$CLUSTER_PATH/authorized_keys" cat "$SSH_HOME/id_rsa.pub" >> "$CLUSTER_PATH/authorized_keys"
echo "INFO: Sovereign Stack just stubbed out '$CLUSTER_PATH/authorized_keys'. Go update it." echo "INFO: Sovereign Stack just stubbed out '$CLUSTER_PATH/authorized_keys'. Go update it."
echo " Add ssh pubkeys for your various management machines, if any. We've stubbed it out" echo " Add ssh pubkeys for your various management machines, if any."
echo " with your ssh pubkey at '$HOME/.ssh/id_rsa.pub'." echo " By default we added your main ssh pubkey: '$HOME/.ssh/id_rsa.pub'."
exit 1 exit 1
fi fi
@ -214,7 +215,6 @@ function new_pass {
function instantiate_vms { function instantiate_vms {
export VPS_HOSTING_TARGET="$VPS_HOSTING_TARGET" export VPS_HOSTING_TARGET="$VPS_HOSTING_TARGET"
export RUN_CERT_RENEWAL="$RUN_CERT_RENEWAL"
export BTC_CHAIN="$BTC_CHAIN" export BTC_CHAIN="$BTC_CHAIN"
export UPDATE_BTCPAY="$UPDATE_BTCPAY" export UPDATE_BTCPAY="$UPDATE_BTCPAY"
export RECONFIGURE_BTCPAY_SERVER="$RECONFIGURE_BTCPAY_SERVER" export RECONFIGURE_BTCPAY_SERVER="$RECONFIGURE_BTCPAY_SERVER"
@ -227,12 +227,9 @@ function instantiate_vms {
FQDN= FQDN=
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME" export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
if [ ! -f "$SITE_PATH/site_definition" ]; then
echo "ERROR: Something went wrong. Your site_definition is missing."
exit 1
fi
source "$SITE_PATH/site_definition" source "$SITE_PATH/site_definition"
source ./domain_env.sh
# VALIDATE THE INPUT from the ENVFILE # VALIDATE THE INPUT from the ENVFILE
if [ -z "$DOMAIN_NAME" ]; then if [ -z "$DOMAIN_NAME" ]; then
@ -240,34 +237,10 @@ function instantiate_vms {
exit 1 exit 1
fi fi
# TODO, ensure VPS_HOSTING_TARGET is in range.
export NEXTCLOUD_FQDN="$NEXTCLOUD_HOSTNAME.$DOMAIN_NAME"
export BTCPAY_FQDN="$BTCPAY_HOSTNAME.$DOMAIN_NAME"
export BTCPAY_USER_FQDN="$BTCPAY_HOSTNAME_IN_CERT.$DOMAIN_NAME"
export WWW_FQDN="$WWW_HOSTNAME.$DOMAIN_NAME"
export GITEA_FQDN="$GITEA_HOSTNAME.$DOMAIN_NAME"
export NOSTR_FQDN="$NOSTR_HOSTNAME.$DOMAIN_NAME"
export ADMIN_ACCOUNT_USERNAME="info"
export CERTIFICATE_EMAIL_ADDRESS="$ADMIN_ACCOUNT_USERNAME@$DOMAIN_NAME"
export REMOTE_NEXTCLOUD_PATH="$REMOTE_HOME/nextcloud"
export REMOTE_GITEA_PATH="$REMOTE_HOME/gitea"
export BTC_CHAIN="$BTC_CHAIN"
export WWW_INSTANCE_TYPE="$WWW_INSTANCE_TYPE"
export BTCPAY_ADDITIONAL_HOSTNAMES="$BTCPAY_ADDITIONAL_HOSTNAMES"
# ensure the
if [ ! -f "$PROJECT_PATH/project_definition" ]; then
echo "ERROR: Your project_definition is not set."
exit 1
fi
source "$PROJECT_PATH/project_definition"
if [ "$VPS_HOSTING_TARGET" = lxd ]; then if [ "$VPS_HOSTING_TARGET" = lxd ]; then
# first let's get the DISK_TO_USE and DATA_PLANE_MACVLAN_INTERFACE from the ss-config # first let's get the DISK_TO_USE and DATA_PLANE_MACVLAN_INTERFACE from the ss-config
# which is set up during LXD cluster creation ss-cluster. # which is set up during LXD cluster creation ss-cluster.
LXD_SS_CONFIG_LINE="$(lxc network list --format csv | grep ss-config)" LXD_SS_CONFIG_LINE="$(lxc network list --format csv | grep lxdbrSS | grep ss-config)"
CONFIG_ITEMS="$(echo "$LXD_SS_CONFIG_LINE" | awk -F'"' '{print $2}')" CONFIG_ITEMS="$(echo "$LXD_SS_CONFIG_LINE" | awk -F'"' '{print $2}')"
DATA_PLANE_MACVLAN_INTERFACE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f2)" DATA_PLANE_MACVLAN_INTERFACE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f2)"
DISK_TO_USE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f3)" DISK_TO_USE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f3)"
@ -286,17 +259,6 @@ function instantiate_vms {
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"
export VIRTUAL_MACHINE="$VIRTUAL_MACHINE"
BACKUP_TIMESTAMP="$(date +"%Y-%m")"
UNIX_BACKUP_TIMESTAMP="$(date +%s)"
export REMOTE_BACKUP_PATH="$REMOTE_HOME/backups/$VIRTUAL_MACHINE/$BACKUP_TIMESTAMP"
LOCAL_BACKUP_PATH="$SITE_PATH/backups/$VIRTUAL_MACHINE/$BACKUP_TIMESTAMP"
export LOCAL_BACKUP_PATH="$LOCAL_BACKUP_PATH"
export BACKUP_TIMESTAMP="$BACKUP_TIMESTAMP"
export UNIX_BACKUP_TIMESTAMP="$UNIX_BACKUP_TIMESTAMP"
export REMOTE_CERT_DIR="$REMOTE_CERT_BASE_DIR/$FQDN"
# ensure the admin has set the MAC address for the base image. # ensure the admin has set the MAC address for the base image.
if [ -z "$SOVEREIGN_STACK_MAC_ADDRESS" ]; then if [ -z "$SOVEREIGN_STACK_MAC_ADDRESS" ]; then
@ -304,11 +266,6 @@ function instantiate_vms {
exit 1 exit 1
fi fi
if [ ! -d "$LOCAL_BACKUP_PATH" ]; then
mkdir -p "$LOCAL_BACKUP_PATH"
BACKUP_PATH_CREATED=true
fi
DDNS_HOST= DDNS_HOST=
MIGRATE_VPS=false MIGRATE_VPS=false
if [ "$VIRTUAL_MACHINE" = www ]; then if [ "$VIRTUAL_MACHINE" = www ]; then
@ -317,7 +274,7 @@ function instantiate_vms {
fi fi
VPS_HOSTNAME="$WWW_HOSTNAME" VPS_HOSTNAME="$WWW_HOSTNAME"
MAC_ADDRESS_TO_PROVISION="$WWW_MAC_ADDRESS" MAC_ADDRESS_TO_PROVISION="$WWW_SERVER_MAC_ADDRESS"
DDNS_HOST="$WWW_HOSTNAME" DDNS_HOST="$WWW_HOSTNAME"
ROOT_DISK_SIZE_GB="$((ROOT_DISK_SIZE_GB + NEXTCLOUD_SPACE_GB))" ROOT_DISK_SIZE_GB="$((ROOT_DISK_SIZE_GB + NEXTCLOUD_SPACE_GB))"
if [ "$MIGRATE_WWW" = true ]; then if [ "$MIGRATE_WWW" = true ]; then
@ -330,7 +287,7 @@ function instantiate_vms {
DDNS_HOST="$BTCPAY_HOSTNAME" DDNS_HOST="$BTCPAY_HOSTNAME"
VPS_HOSTNAME="$BTCPAY_HOSTNAME" VPS_HOSTNAME="$BTCPAY_HOSTNAME"
MAC_ADDRESS_TO_PROVISION="$BTCPAY_MAC_ADDRESS" MAC_ADDRESS_TO_PROVISION="$BTCPAYSERVER_MAC_ADDRESS"
if [ "$BTC_CHAIN" = mainnet ]; then if [ "$BTC_CHAIN" = mainnet ]; then
ROOT_DISK_SIZE_GB=150 ROOT_DISK_SIZE_GB=150
elif [ "$BTC_CHAIN" = testnet ]; then elif [ "$BTC_CHAIN" = testnet ]; then
@ -352,8 +309,25 @@ 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//./-}"
#${PROJECT_NAME//./-}- BACKUP_TIMESTAMP="$(date +"%Y-%m")"
UNIX_BACKUP_TIMESTAMP="$(date +%s)"
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_BACKUP_PATH="$REMOTE_BACKUP_PATH" export REMOTE_BACKUP_PATH="$REMOTE_BACKUP_PATH"
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.
if [ "$VPS_HOSTING_TARGET" = aws ]; then if [ "$VPS_HOSTING_TARGET" = aws ]; then
@ -383,7 +357,8 @@ function instantiate_vms {
fi fi
# get a backup of the machine. This is what we restore to the new VPS. # get a backup of the machine. This is what we restore to the new VPS.
echo "INFO: Machine exists. Since we're going to delete it, let's grab a backup. We don't need to restore services since we're deleting it." echo "INFO: Machine exists. Since we're going to delete it, let's grab a backup. "
echo " We don't need to restore services since we're deleting it."
./deployment/deploy_vms.sh ./deployment/deploy_vms.sh
# delete the remote VPS. # delete the remote VPS.
@ -411,7 +386,8 @@ function instantiate_vms {
fi fi
else else
if [ "$MIGRATE_VPS" = true ]; then if [ "$MIGRATE_VPS" = true ]; then
echo "INFO: User has indicated to delete the machine, but it doesn't exist. Going to create it anyway." echo "INFO: User has indicated to delete the machine, but it doesn't exist."
echo " Going to create it anyway."
fi fi
# The machine does not exist. Let's bring it into existence, restoring from latest backup. # The machine does not exist. Let's bring it into existence, restoring from latest backup.
@ -419,13 +395,6 @@ function instantiate_vms {
./deployment/deploy_vms.sh ./deployment/deploy_vms.sh
fi fi
done
}
function run_domain {
# if the local docker client isn't logged in, do so; # if the local docker client isn't logged in, do so;
# this helps prevent docker pull errors since they throttle. # this helps prevent docker pull errors since they throttle.
if [ ! -f "$HOME/.docker/config.json" ]; then if [ ! -f "$HOME/.docker/config.json" ]; then
@ -433,27 +402,18 @@ function run_domain {
fi fi
# this tells our local docker client to target the remote endpoint via SSH # this tells our local docker client to target the remote endpoint via SSH
export DOCKER_HOST="ssh://ubuntu@$WWW_FQDN" export DOCKER_HOST="ssh://ubuntu@$PRIMARY_WWW_FQDN"
# enable docker swarm mode so we can support docker stacks.
if docker info | grep -q "Swarm: inactive"; then
docker swarm init --advertise-addr enp6s0
fi
bash -c "./deployment/www/go.sh"
export DOCKER_HOST="ssh://ubuntu@$BTCPAY_FQDN"
# enable docker swarm mode so we can support docker stacks. # enable docker swarm mode so we can support docker stacks.
if docker info | grep -q "Swarm: inactive"; then if docker info | grep -q "Swarm: inactive"; then
docker swarm init --advertise-addr enp6s0 docker swarm init --advertise-addr enp6s0
fi fi
bash -c "./deployment/btcpayserver/go.sh" done
echo "Successfully deployed '$DOMAIN_NAME' with git commit '$(cat ./.git/refs/heads/master)' VPS_HOSTING_TARGET=$VPS_HOSTING_TARGET;"
} }
function stub_site_definition { function stub_site_definition {
mkdir -p "$SITE_PATH" "$PROJECT_PATH/sites" mkdir -p "$SITE_PATH" "$PROJECT_PATH/sites"
@ -471,36 +431,21 @@ function stub_site_definition {
cat >"$SITE_DEFINITION_PATH" <<EOL cat >"$SITE_DEFINITION_PATH" <<EOL
#!/bin/bash #!/bin/bash
# Set the domain name for the identity site.
export DOMAIN_NAME="${DOMAIN_NAME}" export DOMAIN_NAME="${DOMAIN_NAME}"
# duplicitiy backup archive password
export DUPLICITY_BACKUP_PASSPHRASE="$(new_pass)" export DUPLICITY_BACKUP_PASSPHRASE="$(new_pass)"
# AWS only # AWS only
#export DDNS_PASSWORD= #export DDNS_PASSWORD=
#export BTCPAY_HOSTNAME_IN_CERT="store"
# Deploy APPS to www
export DEPLOY_GHOST=true export DEPLOY_GHOST=true
export DEPLOY_NEXTCLOUD=true export DEPLOY_NEXTCLOUD=true
export DEPLOY_NOSTR=false export DEPLOY_NOSTR=false
# set if NOSTR_ACCOUNT_PUBKEY=true
export NOSTR_ACCOUNT_PUBKEY="CHANGE_ME" export NOSTR_ACCOUNT_PUBKEY="CHANGE_ME"
export DEPLOY_GITEA=false export DEPLOY_GITEA=false
export DEPLOY_ONION_SITE=false export DEPLOY_ONION_SITE=false
# passwords for WWW apps
## GHOST
export GHOST_MYSQL_PASSWORD="$(new_pass)" export GHOST_MYSQL_PASSWORD="$(new_pass)"
export GHOST_MYSQL_ROOT_PASSWORD="$(new_pass)" export GHOST_MYSQL_ROOT_PASSWORD="$(new_pass)"
## NEXTCLOUD
export NEXTCLOUD_MYSQL_PASSWORD="$(new_pass)" export NEXTCLOUD_MYSQL_PASSWORD="$(new_pass)"
export NEXTCLOUD_MYSQL_ROOT_PASSWORD="$(new_pass)" export NEXTCLOUD_MYSQL_ROOT_PASSWORD="$(new_pass)"
## GITEA
export GITEA_MYSQL_PASSWORD="$(new_pass)" export GITEA_MYSQL_PASSWORD="$(new_pass)"
export GITEA_MYSQL_ROOT_PASSWORD="$(new_pass)" export GITEA_MYSQL_ROOT_PASSWORD="$(new_pass)"
@ -526,40 +471,25 @@ function stub_project_definition {
cat >"$PROJECT_DEFINITION_PATH" <<EOL cat >"$PROJECT_DEFINITION_PATH" <<EOL
#!/bin/bash #!/bin/bash
# for more info about this file and how to use it, see # see https://www.sovereign-stack.org/project-definition for more info.
# www.sovereign-stack.org/project-defintion
# Createa a DHCP reservation for the baseline image.
export SOVEREIGN_STACK_MAC_ADDRESS="CHANGE_ME_REQUIRED"
# Create a DHCP reservation for the www/reverse proxy VM.
export DEPLOY_WWW_SERVER=true export DEPLOY_WWW_SERVER=true
export WWW_SERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED" export WWW_SERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED"
export DEPLOY_BTCPAY_SERVER=true
# Create a DHCP reservation for the btcpay server VM.
export DEPLOY_BTCPAY_SERVER=false
export BTCPAYSERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED" export BTCPAYSERVER_MAC_ADDRESS="CHANGE_ME_REQUIRED"
# export BTC_CHAIN=mainnet
# valid are 'regtest', 'testnet', and 'mainnet'
export BTC_CHAIN=regtest
# set to true to enable nginx caching; helps when making website updates.
# export ENABLE_NGINX_CACHING=true # export ENABLE_NGINX_CACHING=true
export PRIMARY_DOMAIN="CHANGE_ME"
# A list of all sites in ~/ss-sites/ that will be deployed under the project. export OTHER_SITES_LIST=
# e.g., 'domain1.tld,domain2.tld,domain3.tld'.
export SITE_LIST="domain1.tld"
EOL EOL
chmod 0744 "$PROJECT_DEFINITION_PATH" chmod 0744 "$PROJECT_DEFINITION_PATH"
echo "INFO: we stubbed a new project_defition for you at '$PROJECT_DEFINITION_PATH'. Go update it yo!" echo "INFO: we stubbed a new project_defition for you at '$PROJECT_DEFINITION_PATH'. Go update it yo!"
echo "INFO: Learn more at https://www.sovereign-stack.org/project-defition/" echo "INFO: Learn more at https://www.sovereign-stack.org/project-definitions/"
exit 1 exit 1
fi fi
# source project defition. # source project defition.
source "$PROJECT_DEFINITION_PATH" source "$PROJECT_DEFINITION_PATH"
} }
@ -568,13 +498,13 @@ EOL
if [ "$VPS_HOSTING_TARGET" = lxd ]; then if [ "$VPS_HOSTING_TARGET" = lxd ]; then
CURRENT_PROJECT="$(lxc info | grep "project:" | awk '{print $2}')" CURRENT_PROJECT="$(lxc info | grep "project:" | awk '{print $2}')"
PROJECT_PATH="$PROJECTS_DIR/$CURRENT_PROJECT" PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_PATH" "$CLUSTER_PATH/projects" mkdir -p "$PROJECT_PATH" "$CLUSTER_PATH/projects"
export PROJECT_PATH="$PROJECT_PATH" export PROJECT_PATH="$PROJECT_PATH"
# create a symlink from ./clusterpath/projects/project # create a symlink from ./clusterpath/projects/project
if [ ! -d "$CLUSTER_PATH/projects/$CURRENT_PROJECT" ]; then if [ ! -d "$CLUSTER_PATH/projects/$PROJECT_NAME" ]; then
ln -s "$PROJECT_PATH" "$CLUSTER_PATH/projects/$CURRENT_PROJECT" ln -s "$PROJECT_PATH" "$CLUSTER_PATH/projects/$PROJECT_NAME"
fi fi
# check if we need to provision a new lxc project. # check if we need to provision a new lxc project.
@ -589,29 +519,36 @@ if [ "$VPS_HOSTING_TARGET" = lxd ]; then
fi fi
# stub out the project definition if needed.
stub_project_definition stub_project_definition
# iterate through our site list as provided by operator from cluster_definition # the DOMAIN_LIST is a complete list of all our domains. We often iterate over this list.
iteration=0 export DOMAIN_LIST="${PRIMARY_DOMAIN},${OTHER_SITES_LIST}"
for DOMAIN_NAME in ${SITE_LIST//,/ }; do export DOMAIN_COUNT=$(("$(echo $DOMAIN_LIST | tr -cd , | wc -c)"+1))
# let's provision our primary domain first.
export DOMAIN_NAME="$PRIMARY_DOMAIN"
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
export PRIMARY_WWW_FQDN="$WWW_HOSTNAME.$DOMAIN_NAME"
stub_site_definition
# bring the vms up under the primary domain name.
instantiate_vms
# let's stub out the rest of our site definitions, if any.
for DOMAIN_NAME in ${OTHER_SITES_LIST//,/ }; do
export DOMAIN_NAME="$DOMAIN_NAME" export DOMAIN_NAME="$DOMAIN_NAME"
export SITE_PATH="$SITES_PATH/$DOMAIN_NAME" export SITE_PATH="$SITES_PATH/$DOMAIN_NAME"
# the vms are named accordignt to the first domain listed.
if [ $iteration = 0 ]; then
# bring the vms up
instantiate_vms
fi
# stub out the site_defition if it's doesn't exist. # stub out the site_defition if it's doesn't exist.
stub_site_definition stub_site_definition
# run the logic for a domain deployment.
run_domain
iteration=$((iteration+1))
done done
# now let's run the www and btcpay-specific provisioning scripts.
bash -c "./deployment/www/go.sh"
bash -c "./deployment/btcpayserver/go.sh"
elif [ "$VPS_HOSTING_TARGET" = aws ]; then elif [ "$VPS_HOSTING_TARGET" = aws ]; then
stub_site_definition stub_site_definition

View File

@ -3,7 +3,10 @@
set -eux set -eux
cd "$(dirname "$0")" cd "$(dirname "$0")"
export DOCKER_HOST="ssh://ubuntu@$BTCPAY_FQDN"
OPEN_URL=false OPEN_URL=false
RUN_SERVICES=false
# we will re-run the btcpayserver provisioning scripts if directed to do so. # we will re-run the btcpayserver provisioning scripts if directed to do so.
# if an update does occur, we grab another backup. # if an update does occur, we grab another backup.
@ -58,8 +61,8 @@ fi
if [ "$OPEN_URL" = true ]; then if [ "$OPEN_URL" = true ]; then
if [ "$VPS_HOSTING_TARGET" = lxd ]; then if [ "$VPS_HOSTING_TARGET" = lxd ]; then
if wait-for-it -t 5 "$WWW_FQDN:80"; then if wait-for-it -t 5 "$PRIMARY_WWW_FQDN:80"; then
xdg-open "http://$WWW_FQDN" > /dev/null 2>&1 xdg-open "http://$PRIMARY_WWW_FQDN" > /dev/null 2>&1
fi fi
else else
if wait-for-it -t 5 "$FQDN:443"; then if wait-for-it -t 5 "$FQDN:443"; then

View File

@ -60,7 +60,7 @@ elif [ "$VPS_HOSTING_TARGET" = lxd ]; then
# create a base image if needed and instantiate a VM. # create a base image if needed and instantiate a VM.
if [ -z "$MAC_ADDRESS_TO_PROVISION" ]; then if [ -z "$MAC_ADDRESS_TO_PROVISION" ]; then
echo "ERROR: You MUST define a MAC Address for all your machines by setting WWW_MAC_ADDRESS, BTCPAY_MAC_ADDRESS in your site defintion." echo "ERROR: You MUST define a MAC Address for all your machines by setting WWW_SERVER_MAC_ADDRESS, BTCPAYSERVER_MAC_ADDRESS in your site defintion."
echo "INFO: IMPORTANT! You MUST have DHCP Reservations for these MAC addresses. You also need static DNS entries." echo "INFO: IMPORTANT! You MUST have DHCP Reservations for these MAC addresses. You also need static DNS entries."
exit 1 exit 1
fi fi

View File

@ -47,9 +47,8 @@ if [ "$VIRTUAL_MACHINE" = www ] || [ "$VIRTUAL_MACHINE" = certonly ]; then
--amazonec2-ami "$AWS_AMI_ID" \ --amazonec2-ami "$AWS_AMI_ID" \
--amazonec2-root-size "$ROOT_DISK_SIZE_GB" \ --amazonec2-root-size "$ROOT_DISK_SIZE_GB" \
--amazonec2-instance-type "$WWW_INSTANCE_TYPE" \ --amazonec2-instance-type "$WWW_INSTANCE_TYPE" \
--engine-label commit="$LATEST_GIT_COMMIT" \
"$FQDN" "$FQDN"
# --engine-label commit="$LATEST_GIT_COMMIT" \
elif [ "$VIRTUAL_MACHINE" = btcpayserver ]; then elif [ "$VIRTUAL_MACHINE" = btcpayserver ]; then
# creates a public VM in AWS and provisions the bcm website. # creates a public VM in AWS and provisions the bcm website.
docker-machine create --driver amazonec2 \ docker-machine create --driver amazonec2 \
@ -62,9 +61,8 @@ elif [ "$VIRTUAL_MACHINE" = btcpayserver ]; then
--amazonec2-ami "$AWS_AMI_ID" \ --amazonec2-ami "$AWS_AMI_ID" \
--amazonec2-root-size "$ROOT_DISK_SIZE_GB" \ --amazonec2-root-size "$ROOT_DISK_SIZE_GB" \
--amazonec2-instance-type "$BTCPAY_INSTANCE_TYPE" \ --amazonec2-instance-type "$BTCPAY_INSTANCE_TYPE" \
--engine-label commit="$LATEST_GIT_COMMIT" \
"$FQDN" "$FQDN"
# --engine-label commit="$LATEST_GIT_COMMIT" \
fi fi
docker-machine scp "$CLUSTER_PATH/authorized_keys" "$FQDN:$REMOTE_HOME/authorized_keys" docker-machine scp "$CLUSTER_PATH/authorized_keys" "$FQDN:$REMOTE_HOME/authorized_keys"

View File

@ -9,12 +9,12 @@ cd "$(dirname "$0")"
# 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
# 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 "$WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --allow-source-mismatch --exclude "$REMOTE_HOME/backups" "$REMOTE_HOME" "file://$REMOTE_BACKUP_PATH" ssh "$PRIMARY_WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --allow-source-mismatch --exclude "$REMOTE_HOME/backups" "$REMOTE_HOME" "file://$REMOTE_BACKUP_PATH"
ssh "$WWW_FQDN" sudo chown -R ubuntu:ubuntu "$REMOTE_BACKUP_PATH" ssh "$PRIMARY_WWW_FQDN" sudo chown -R ubuntu:ubuntu "$REMOTE_BACKUP_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 "$WWW_FQDN:$REMOTE_BACKUP_PATH" "$SSHFS_PATH" sshfs "$PRIMARY_WWW_FQDN:$REMOTE_BACKUP_PATH" "$SSHFS_PATH"
# 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/"

View File

@ -2,6 +2,7 @@
set -ex set -ex
# let's do a refresh of the certificates. Let's Encrypt will not run if it's not time. # let's do a refresh of the certificates. Let's Encrypt will not run if it's not time.
docker pull certbot/certbot:latest docker pull certbot/certbot:latest
@ -20,13 +21,38 @@ if [ "$VPS_HOSTING_TARGET" = aws ]; then
elif [ "$VPS_HOSTING_TARGET" = lxd ]; then elif [ "$VPS_HOSTING_TARGET" = lxd ]; then
# with the lxd side, we are trying to expose ALL OUR services from one IP address, which terminates # with the lxd side, we are trying to expose ALL OUR services from one IP address, which terminates
# at a cachehing reverse proxy that runs nginx. # at a cachehing reverse proxy that runs nginx.
# docker run -it --rm \
# --name certbot \
# -p 80:80 \
# -p 443:443 \
# -v "$REMOTE_HOME/letsencrypt":/etc/letsencrypt \
# -v /var/lib/letsencrypt:/var/lib/letsencrypt \
# -v "$REMOTE_HOME/letsencrypt_logs":/var/log/letsencrypt \
# certbot/certbot certonly -v --noninteractive --agree-tos --key-type ecdsa --standalone --expand -d "$DOMAIN_NAME" -d "$PRIMARY_WWW_FQDN" -d "$BTCPAY_USER_FQDN" -d "$NEXTCLOUD_FQDN" -d "$GITEA_FQDN" -d "$NOSTR_FQDN" --email "$CERTIFICATE_EMAIL_ADDRESS"
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
# with the lxd side, we are trying to expose ALL OUR services from one IP address, which terminates
# at a cachehing reverse proxy that runs nginx.
ssh "$PRIMARY_WWW_FQDN" sudo mkdir -p "$REMOTE_HOME/letsencrypt/$DOMAIN_NAME/_logs"
docker run -it --rm \ docker run -it --rm \
--name certbot \ --name certbot \
-p 80:80 \ -p 80:80 \
-p 443:443 \ -p 443:443 \
-v "$REMOTE_HOME/letsencrypt":/etc/letsencrypt \ -v "$REMOTE_HOME/letsencrypt/$DOMAIN_NAME":/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \ -v /var/lib/letsencrypt:/var/lib/letsencrypt \
-v "$REMOTE_HOME/letsencrypt_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"
done
fi fi

View File

@ -1,9 +1,26 @@
#!/bin/bash #!/bin/bash
set -exuo set -exu
cd "$(dirname "$0")" cd "$(dirname "$0")"
if [ "$DEPLOY_GHOST" = true ]; then # Create the nginx config file which covers all domains.
bash -c ./stub_nginxconf.sh
# redirect all docker commands to the remote host.
export DOCKER_HOST="ssh://ubuntu@$PRIMARY_WWW_FQDN"
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
### Let's check to ensure all the requiredsettings are set.
if [ "$DEPLOY_GHOST" = true ]; then
if [ -z "$GHOST_MYSQL_PASSWORD" ]; then if [ -z "$GHOST_MYSQL_PASSWORD" ]; then
echo "ERROR: Ensure GHOST_MYSQL_PASSWORD is configured in your site_definition." echo "ERROR: Ensure GHOST_MYSQL_PASSWORD is configured in your site_definition."
exit 1 exit 1
@ -13,9 +30,9 @@ if [ "$DEPLOY_GHOST" = true ]; then
echo "ERROR: Ensure GHOST_MYSQL_ROOT_PASSWORD is configured in your site_definition." echo "ERROR: Ensure GHOST_MYSQL_ROOT_PASSWORD is configured in your site_definition."
exit 1 exit 1
fi fi
fi fi
if [ "$DEPLOY_GITEA" = true ]; then if [ "$DEPLOY_GITEA" = true ]; then
if [ -z "$GITEA_MYSQL_PASSWORD" ]; then if [ -z "$GITEA_MYSQL_PASSWORD" ]; then
echo "ERROR: Ensure GITEA_MYSQL_PASSWORD is configured in your site_definition." echo "ERROR: Ensure GITEA_MYSQL_PASSWORD is configured in your site_definition."
exit 1 exit 1
@ -24,9 +41,9 @@ if [ "$DEPLOY_GITEA" = true ]; then
echo "ERROR: Ensure GITEA_MYSQL_ROOT_PASSWORD is configured in your site_definition." echo "ERROR: Ensure GITEA_MYSQL_ROOT_PASSWORD is configured in your site_definition."
exit 1 exit 1
fi fi
fi fi
if [ "$DEPLOY_NEXTCLOUD" = true ]; then if [ "$DEPLOY_NEXTCLOUD" = true ]; then
if [ -z "$NEXTCLOUD_MYSQL_ROOT_PASSWORD" ]; then if [ -z "$NEXTCLOUD_MYSQL_ROOT_PASSWORD" ]; then
echo "ERROR: Ensure NEXTCLOUD_MYSQL_ROOT_PASSWORD is configured in your site_definition." echo "ERROR: Ensure NEXTCLOUD_MYSQL_ROOT_PASSWORD is configured in your site_definition."
exit 1 exit 1
@ -36,9 +53,9 @@ if [ "$DEPLOY_NEXTCLOUD" = true ]; then
echo "ERROR: Ensure NEXTCLOUD_MYSQL_PASSWORD is configured in your site_definition." echo "ERROR: Ensure NEXTCLOUD_MYSQL_PASSWORD is configured in your site_definition."
exit 1 exit 1
fi fi
fi fi
if [ "$DEPLOY_NOSTR" = true ]; then if [ "$DEPLOY_NOSTR" = true ]; then
if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then
echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition."
exit 1 exit 1
@ -48,47 +65,45 @@ if [ "$DEPLOY_NOSTR" = true ]; then
echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition."
exit 1 exit 1
fi fi
fi fi
if [ -z "$DUPLICITY_BACKUP_PASSPHRASE" ]; then if [ -z "$DUPLICITY_BACKUP_PASSPHRASE" ]; then
echo "ERROR: Ensure DUPLICITY_BACKUP_PASSPHRASE is configured in your site_definition." echo "ERROR: Ensure DUPLICITY_BACKUP_PASSPHRASE is configured in your site_definition."
exit 1 exit 1
fi fi
if [ -z "$DOMAIN_NAME" ]; then if [ -z "$DOMAIN_NAME" ]; then
echo "ERROR: Ensure DOMAIN_NAME is configured in your site_definition." echo "ERROR: Ensure DOMAIN_NAME is configured in your site_definition."
exit 1 exit 1
fi fi
if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then
echo "ERROR: You MUST specify a Nostr public key. This is how you get all your social features." echo "ERROR: You MUST specify a Nostr public key. This is how you get all your social features."
echo "INFO: Go to your site_definition file and set the NOSTR_ACCOUNT_PUBKEY variable." echo "INFO: Go to your site_definition file and set the NOSTR_ACCOUNT_PUBKEY variable."
exit 1 exit 1
fi fi
bash -c ./stub_nginxconf.sh TOR_CONFIG_PATH=
TOR_CONFIG_PATH= if [ "$DEPLOY_NEXTCLOUD" = true ]; then
ssh "$PRIMARY_WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/db/data"
ssh "$PRIMARY_WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/db/logs"
ssh "$PRIMARY_WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/html"
fi
ssh "$WWW_FQDN" mkdir -p "$REMOTE_HOME/ghost_site" "$REMOTE_HOME/ghost_db" if [ "$DEPLOY_GITEA" = true ]; then
if [ "$DEPLOY_NEXTCLOUD" = true ]; then
ssh "$WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/db/data"
ssh "$WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/db/logs"
ssh "$WWW_FQDN" "mkdir -p $REMOTE_NEXTCLOUD_PATH/html"
fi
if [ "$DEPLOY_GITEA" = true ]; then
ssh "$FQDN" "mkdir -p $REMOTE_GITEA_PATH/data $REMOTE_GITEA_PATH/db" ssh "$FQDN" "mkdir -p $REMOTE_GITEA_PATH/data $REMOTE_GITEA_PATH/db"
fi fi
done
### The next series of commands
# stop services. # stop services.
if docker stack list --format "{{.Name}}" | grep -q webstack; then if docker stack list --format "{{.Name}}" | grep -q webstack; then
docker stack rm webstack docker stack rm webstack
sleep 15 sleep 15
fi fi
if [ "$BACKUP_WWW" = true ]; then if [ "$BACKUP_WWW" = true ]; then
./backup.sh ./backup.sh
fi fi
@ -98,7 +113,10 @@ if [ "$RESTORE_WWW" = true ]; then
# just created, we know that we'll deploy fresh. # just created, we know that we'll deploy fresh.
./restore.sh ./restore.sh
else else
if [ "$RUN_CERT_RENEWAL" = true ]; then
./generate_certs.sh ./generate_certs.sh
fi
fi fi
@ -108,8 +126,8 @@ if [ "$DEPLOY_ONION_SITE" = true ]; then
# if the tor folder doesn't exist, we provision a new one. Otherwise you need to restore. # if the tor folder doesn't exist, we provision a new one. Otherwise you need to restore.
# this is how we generate a new torv3 endpoint. # this is how we generate a new torv3 endpoint.
if ! ssh "$WWW_FQDN" "[ -d $REMOTE_HOME/tor/www ]"; then if ! ssh "$PRIMARY_WWW_FQDN" "[ -d $REMOTE_HOME/tor/www ]"; then
ssh "$WWW_FQDN" "mkdir -p $REMOTE_HOME/tor" ssh "$PRIMARY_WWW_FQDN" "mkdir -p $REMOTE_HOME/tor"
TOR_CONFIG_PATH="$(pwd)/tor/torrc-init" TOR_CONFIG_PATH="$(pwd)/tor/torrc-init"
export TOR_CONFIG_PATH="$TOR_CONFIG_PATH" export TOR_CONFIG_PATH="$TOR_CONFIG_PATH"
docker stack deploy -c ./tor.yml torstack docker stack deploy -c ./tor.yml torstack
@ -118,37 +136,31 @@ if [ "$DEPLOY_ONION_SITE" = true ]; then
sleep 20 sleep 20
fi fi
ONION_ADDRESS="$(ssh "$WWW_FQDN" sudo cat "${REMOTE_HOME}"/tor/www/hostname)" ONION_ADDRESS="$(ssh "$PRIMARY_WWW_FQDN" sudo cat "${REMOTE_HOME}"/tor/www/hostname)"
export ONION_ADDRESS="$ONION_ADDRESS" export ONION_ADDRESS="$ONION_ADDRESS"
# # Since we run a separate ghost process, we create a new directory and symlink it to the original # # Since we run a separate ghost process, we create a new directory and symlink it to the original
# if ! ssh "$WWW_FQDN" "[ -L $REMOTE_HOME/tor_ghost ]"; then # if ! ssh "$PRIMARY_WWW_FQDN" "[ -L $REMOTE_HOME/tor_ghost ]"; then
# ssh "$WWW_FQDN" ln -s "$REMOTE_HOME/ghost_site/themes $REMOTE_HOME/tor_ghost/themes" # ssh "$PRIMARY_WWW_FQDN" ln -s "$REMOTE_HOME/ghost_site/themes $REMOTE_HOME/tor_ghost/themes"
# fi # fi
fi fi
#if [ "$RUN_SERVICES" = true ]; then
mkdir -p "$SITE_PATH/stacks"
DOCKER_YAML_PATH="$SITE_PATH/stacks/www.yml"
export DOCKER_YAML_PATH="$DOCKER_YAML_PATH"
bash -c ./stub_docker_yml.sh bash -c ./stub_docker_yml.sh
docker stack deploy -c "$DOCKER_YAML_PATH" webstack # # 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:443"
# start a browser session; point it to port 80 to ensure HTTPS redirect. # # open bowser tabs.
wait-for-it -t 320 "$WWW_FQDN:80" # if [ "$DEPLOY_GHOST" = true ]; then
wait-for-it -t 320 "$WWW_FQDN:443" # xdg-open "http://$PRIMARY_WWW_FQDN" > /dev/null 2>&1
# fi
# open bowser tabs. # if [ "$DEPLOY_NEXTCLOUD" = true ]; then
if [ "$DEPLOY_GHOST" = true ]; then # xdg-open "http://$NEXTCLOUD_FQDN" > /dev/null 2>&1
xdg-open "http://$WWW_FQDN" > /dev/null 2>&1 # fi
fi
if [ "$DEPLOY_NEXTCLOUD" = true ]; then # if [ "$DEPLOY_GITEA" = true ]; then
xdg-open "http://$NEXTCLOUD_FQDN" > /dev/null 2>&1 # xdg-open "http://$GITEA_FQDN" > /dev/null 2>&1
fi # fi
# #fi
if [ "$DEPLOY_GITEA" = true ]; then
xdg-open "http://$GITEA_FQDN" > /dev/null 2>&1
fi
#fi

View File

@ -7,13 +7,13 @@ set -exu
# indeed, our first step is the delete the home directory on the remote server. # indeed, our first step is the delete the home directory on the remote server.
# delete the home directory so we know we are restoring all files from the duplicity archive. # delete the home directory so we know we are restoring all files from the duplicity archive.
ssh "$WWW_FQDN" sudo rm -rf "$REMOTE_HOME/*" ssh "$PRIMARY_WWW_FQDN" sudo rm -rf "$REMOTE_HOME/*"
# scp our local backup directory to the remote machine # scp our local backup directory to the remote machine
ssh "$WWW_FQDN" mkdir -p "$REMOTE_BACKUP_PATH" ssh "$PRIMARY_WWW_FQDN" mkdir -p "$REMOTE_BACKUP_PATH"
# TODO instead of scp the files up there, lets' mount the local backup folder to a remote folder then just run a duplicity restore. # TODO instead of scp the files up there, lets' mount the local backup folder to a remote folder then just run a duplicity restore.
scp -r "$LOCAL_BACKUP_PATH/" "$WWW_FQDN:$REMOTE_HOME/backups/$VIRTUAL_MACHINE" scp -r "$LOCAL_BACKUP_PATH" "$PRIMARY_WWW_FQDN:$REMOTE_BACKUP_PATH"
# now we run duplicity to restore the archive. # now we run duplicity to restore the archive.
ssh "$WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --force restore "file://$REMOTE_BACKUP_PATH/" "$REMOTE_HOME/" ssh "$PRIMARY_WWW_FQDN" sudo PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --force restore "file://$REMOTE_BACKUP_PATH/$BACKUP_TIMESTAMP" "$REMOTE_HOME/"

View File

@ -1,40 +1,119 @@
#!/bin/bash #!/bin/bash
set -eu set -eux
cd "$(dirname "$0")" cd "$(dirname "$0")"
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. ssh "$PRIMARY_WWW_FQDN" sudo rm -rf /home/ubuntu/ghost
echo "" > "$DOCKER_YAML_PATH" sleep 4
cat >>"$DOCKER_YAML_PATH" <<EOL
#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" version: "3.8"
services: services:
EOL EOL
# This is the ghost for HTTPS (not over Tor) # This is the ghost for HTTPS (not over Tor)
cat >>"$DOCKER_YAML_PATH" <<EOL cat >>"$DOCKER_YAML_PATH" <<EOL
ghost: ghost-${domain_number}:
image: ${GHOST_IMAGE} image: ${GHOST_IMAGE}
networks: networks:
- ghost-net - ghostnet-${domain_number}
- ghostdb-net - ghostdbnet-${domain_number}
volumes: volumes:
- ${REMOTE_HOME}/ghost_site:/var/lib/ghost/content - ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/ghost:/var/lib/ghost/content
environment: environment:
- url=https://${WWW_FQDN} - url=https://${PRIMARY_WWW_FQDN}
- database__client=mysql - database__client=mysql
- database__connection__host=ghostdb - database__connection__host=ghostdb-${domain_number}
- database__connection__user=ghost - database__connection__user=ghost
- database__connection__password=\${GHOST_MYSQL_PASSWORD} - database__connection__password=\${GHOST_MYSQL_PASSWORD}
- database__connection__database=ghost - database__connection__database=ghost
@ -44,12 +123,12 @@ cat >>"$DOCKER_YAML_PATH" <<EOL
restart_policy: restart_policy:
condition: on-failure condition: on-failure
ghostdb: ghostdb-${domain_number}:
image: ${GHOST_DB_IMAGE} image: ${GHOST_DB_IMAGE}
networks: networks:
- ghostdb-net - ghostdbnet-${domain_number}
volumes: volumes:
- ${REMOTE_HOME}/ghost_db:/var/lib/mysql - ${REMOTE_HOME}/ghost/${DOMAIN_NAME}/db:/var/lib/mysql
environment: environment:
- MYSQL_ROOT_PASSWORD=\${GHOST_MYSQL_ROOT_PASSWORD} - MYSQL_ROOT_PASSWORD=\${GHOST_MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=ghost - MYSQL_DATABASE=ghost
@ -62,247 +141,214 @@ cat >>"$DOCKER_YAML_PATH" <<EOL
EOL EOL
if [ "$DEPLOY_NEXTCLOUD" = true ]; then # if [ "$DEPLOY_NEXTCLOUD" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
nextcloud-db: # nextcloud-db:
image: ${NEXTCLOUD_DB_IMAGE} # image: ${NEXTCLOUD_DB_IMAGE}
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb_read_only_compressed=OFF # command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb_read_only_compressed=OFF
networks: # networks:
- nextclouddb-net # - nextclouddb-net
volumes: # volumes:
- ${REMOTE_HOME}/nextcloud/db/data:/var/lib/mysql # - ${REMOTE_HOME}/nextcloud/db/data:/var/lib/mysql
environment: # environment:
- MARIADB_ROOT_PASSWORD=\${NEXTCLOUD_MYSQL_ROOT_PASSWORD} # - MARIADB_ROOT_PASSWORD=\${NEXTCLOUD_MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=\${NEXTCLOUD_MYSQL_PASSWORD} # - MYSQL_PASSWORD=\${NEXTCLOUD_MYSQL_PASSWORD}
- MYSQL_DATABASE=nextcloud # - MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud # - MYSQL_USER=nextcloud
deploy: # deploy:
restart_policy: # restart_policy:
condition: on-failure # condition: on-failure
nextcloud: # nextcloud:
image: ${NEXTCLOUD_IMAGE} # image: ${NEXTCLOUD_IMAGE}
networks: # networks:
- nextclouddb-net # - nextclouddb-net
- nextcloud-net # - nextcloud-net
volumes: # volumes:
- ${REMOTE_HOME}/nextcloud/html:/var/www/html # - ${REMOTE_HOME}/nextcloud/html:/var/www/html
environment: # environment:
- MYSQL_PASSWORD=\${NEXTCLOUD_MYSQL_PASSWORD} # - MYSQL_PASSWORD=\${NEXTCLOUD_MYSQL_PASSWORD}
- MYSQL_DATABASE=nextcloud # - MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud # - MYSQL_USER=nextcloud
- MYSQL_HOST=nextcloud-db # - MYSQL_HOST=nextcloud-db
- NEXTCLOUD_TRUSTED_DOMAINS=${DOMAIN_NAME} # - NEXTCLOUD_TRUSTED_DOMAINS=${DOMAIN_NAME}
- OVERWRITEHOST=${NEXTCLOUD_FQDN} # - OVERWRITEHOST=${NEXTCLOUD_FQDN}
- OVERWRITEPROTOCOL=https # - OVERWRITEPROTOCOL=https
- SERVERNAME=${NEXTCLOUD_FQDN} # - SERVERNAME=${NEXTCLOUD_FQDN}
deploy: # deploy:
restart_policy: # restart_policy:
condition: on-failure # condition: on-failure
EOL # EOL
fi # fi
if [ "$DEPLOY_NOSTR" = true ]; then # if [ "$DEPLOY_GITEA" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
# TODO # gitea:
# image: ${GITEA_IMAGE}
# volumes:
# - ${REMOTE_GITEA_PATH}/data:/data
# - /etc/timezone:/etc/timezone:ro
# - /etc/localtime:/etc/localtime:ro
# environment:
# - USER_UID=1000
# - USER_GID=1000
# - ROOT_URL=https://${GITEA_FQDN}
# - GITEA__database__DB_TYPE=mysql
# - GITEA__database__HOST=gitea-db:3306
# - GITEA__database__NAME=gitea
# - GITEA__database__USER=gitea
# - GITEA__PASSWD=\${GITEA_MYSQL_PASSWORD}
# networks:
# - gitea-net
# - giteadb-net
# deploy:
# restart_policy:
# condition: on-failure
# gitea-db:
EOL # image: ${GITEA_DB_IMAGE}
fi # networks:
# - giteadb-net
if [ "$DEPLOY_GITEA" = true ]; then # volumes:
cat >>"$DOCKER_YAML_PATH" <<EOL # - ${REMOTE_GITEA_PATH}/db:/var/lib/mysql
gitea: # environment:
image: ${GITEA_IMAGE} # - MYSQL_ROOT_PASSWORD=\${GITEA_MYSQL_ROOT_PASSWORD}
volumes: # - MYSQL_PASSWORD=\${GITEA_MYSQL_PASSWORD}
- ${REMOTE_GITEA_PATH}/data:/data # - MYSQL_DATABASE=gitea
- /etc/timezone:/etc/timezone:ro # - MYSQL_USER=gitea
- /etc/localtime:/etc/localtime:ro # deploy:
environment: # restart_policy:
- USER_UID=1000 # condition: on-failure
- USER_GID=1000 # EOL
- ROOT_URL=https://${GITEA_FQDN} # fi
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=gitea-db:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__PASSWD=\${GITEA_MYSQL_PASSWORD}
networks:
- gitea-net
- giteadb-net
deploy:
restart_policy:
condition: on-failure
gitea-db:
image: ${GITEA_DB_IMAGE}
networks:
- giteadb-net
volumes:
- ${REMOTE_GITEA_PATH}/db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=\${GITEA_MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=\${GITEA_MYSQL_PASSWORD}
- MYSQL_DATABASE=gitea
- MYSQL_USER=gitea
deploy:
restart_policy:
condition: on-failure
EOL
fi
if [ "$DEPLOY_ONION_SITE" = true ]; then # if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
# a hidden service that routes to the nginx container at http://onionurl.onion server block # # a hidden service that routes to the nginx container at http://onionurl.onion server block
tor-onion: # tor-onion:
image: tor:latest # image: tor:latest
networks: # networks:
- tor-net # - tor-net
volumes: # volumes:
- ${REMOTE_HOME}/tor:/var/lib/tor # - ${REMOTE_HOME}/tor:/var/lib/tor
- tor-logs:/var/log/tor # - tor-logs:/var/log/tor
configs: # configs:
- source: tor-config # - source: tor-config
target: /etc/tor/torrc # target: /etc/tor/torrc
mode: 0644 # mode: 0644
deploy: # deploy:
mode: replicated # mode: replicated
replicas: 1 # replicas: 1
restart_policy: # restart_policy:
condition: on-failure # condition: on-failure
tor-ghost: # tor-ghost:
image: ${GHOST_IMAGE} # image: ${GHOST_IMAGE}
networks: # networks:
- ghostdb-net # - ghostdb-net
- ghost-net # - ghost-net
volumes: # volumes:
- ${REMOTE_HOME}/tor_ghost:/var/lib/ghost/content # - ${REMOTE_HOME}/tor_ghost:/var/lib/ghost/content
environment: # environment:
- url=https://${ONION_ADDRESS} # - url=https://${ONION_ADDRESS}
- database__client=mysql # - database__client=mysql
- database__connection__host=ghostdb # - database__connection__host=ghostdb
- database__connection__user=ghost # - database__connection__user=ghost
- database__connection__password=\${GHOST_MYSQL_PASSWORD} # - database__connection__password=\${GHOST_MYSQL_PASSWORD}
- database__connection__database=ghost # - database__connection__database=ghost
deploy: # deploy:
restart_policy: # restart_policy:
condition: on-failure # condition: on-failure
EOL # EOL
fi # fi
#https://github.com/fiatjaf/expensive-relay # if [ "$DEPLOY_ONION_SITE" = true ]; then
# NOSTR RELAY WHICH REQUIRES PAYMENTS. # cat >>"$DOCKER_YAML_PATH" <<EOL
cat >>"$DOCKER_YAML_PATH" <<EOL # - torghost-net
nginx: # EOL
image: ${NGINX_IMAGE} # fi
ports:
- 0.0.0.0:443:443
- 0.0.0.0:80:80
networks:
- ghost-net
EOL
if [ "$DEPLOY_ONION_SITE" = true ]; then # if [ "$DEPLOY_NEXTCLOUD" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
- torghost-net # - nextcloud-net
EOL # EOL
fi # fi
if [ "$DEPLOY_NEXTCLOUD" = true ]; then # if [ "$DEPLOY_GITEA" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
- nextcloud-net # - gitea-net
EOL # EOL
fi # fi
if [ "$DEPLOY_GITEA" = true ]; then # if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
- gitea-net # - tor-net
EOL # EOL
fi # fi
if [ "$DEPLOY_ONION_SITE" = true ]; then # if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
- tor-net
EOL
fi
# the rest of the nginx config # volumes:
cat >>"$DOCKER_YAML_PATH" <<EOL # tor-data:
volumes: # tor-logs:
- ${REMOTE_HOME}/letsencrypt:/etc/letsencrypt:ro
configs:
- source: nginx-config
target: /etc/nginx/nginx.conf
deploy:
restart_policy:
condition: on-failure
EOL # EOL
# fi
if [ "$DEPLOY_ONION_SITE" = true ]; then # #-------------------------
cat >>"$DOCKER_YAML_PATH" <<EOL
volumes:
tor-data:
tor-logs:
EOL
fi
#-------------------------
# networks ---------------------- # networks ----------------------
cat >>"$DOCKER_YAML_PATH" <<EOL cat >>"$DOCKER_YAML_PATH" <<EOL
networks: networks:
EOL EOL
if [ "$DEPLOY_GHOST" = true ]; then if [ "$DEPLOY_GHOST" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL cat >>"$DOCKER_YAML_PATH" <<EOL
ghost-net: ghostnet-${domain_number}:
ghostdb-net: name: "reverse-proxy_ghostnet-${domain_number}"
external: true
ghostdbnet-${domain_number}:
EOL EOL
fi fi
if [ "$DEPLOY_NEXTCLOUD" = true ]; then # if [ "$DEPLOY_NEXTCLOUD" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
nextclouddb-net: # nextclouddb-net:
nextcloud-net: # nextcloud-net:
EOL # EOL
fi # fi
if [ "$DEPLOY_GITEA" = true ]; then # if [ "$DEPLOY_GITEA" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
gitea-net: # gitea-net:
giteadb-net: # giteadb-net:
EOL # EOL
fi # fi
if [ "$DEPLOY_ONION_SITE" = true ]; then # if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
tor-net: # tor-net:
torghost-net: # torghost-net:
EOL # EOL
fi # fi
# ------------------------------- # # -------------------------------
# configs ---------------------- # if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$DOCKER_YAML_PATH" <<EOL # cat >>"$DOCKER_YAML_PATH" <<EOL
# tor-config:
# file: $(pwd)/tor/torrc
# EOL
# fi
# # -----------------------------
configs:
nginx-config:
file: ${PROJECT_PATH}/nginx.conf
EOL
if [ "$DEPLOY_ONION_SITE" = true ]; then docker stack deploy -c "$DOCKER_YAML_PATH" "$STACK_TAG"
cat >>"$DOCKER_YAML_PATH" <<EOL
tor-config: domain_number=$((domain_number+1))
file: $(pwd)/tor/torrc done
EOL
fi
# -----------------------------

View File

@ -4,17 +4,29 @@ set -eu
cd "$(dirname "$0")" cd "$(dirname "$0")"
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. # here's the NGINX config. We support ghost and nextcloud.
NGINX_CONF_PATH="$PROJECT_PATH/nginx.conf" NGINX_CONF_PATH="$PROJECT_PATH/nginx.conf"
# clear the existing nginx config.
echo "" > "$NGINX_CONF_PATH" echo "" > "$NGINX_CONF_PATH"
cat >>"$NGINX_CONF_PATH" <<EOL
# iterate over all our domains and create the nginx config file.
iteration=0
echo "DOMAIN_LIST: $DOMAIN_LIST"
for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do
export DOMAIN_NAME="$DOMAIN_NAME"
export SITE_PATH="$SITES_PATH/$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 ../../reset_env.sh
source "$SITE_PATH/site_definition"
source ../../domain_env.sh
echo "Doing DOMAIN_NAME: $DOMAIN_NAME"
if [ $iteration = 0 ]; then
cat >>"$NGINX_CONF_PATH" <<EOL
events { events {
worker_connections 1024; worker_connections 1024;
} }
@ -31,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_field_size 500k;
http2_max_header_size 500k; http2_max_header_size 500k;
# Needed websocket support (used by Ledger hardware wallets) # Needed websocket support (used by Ledger hardware wallets)
@ -43,14 +54,14 @@ http {
# return 403 for all non-explicit hostnames # return 403 for all non-explicit hostnames
server { server {
listen 80 default_server; listen 80 default_server;
return 403; return 301 https://${WWW_FQDN}\$request_uri;
} }
EOL EOL
fi
# ghost http to https redirects.
# ghost http to https redirects. cat >>"$NGINX_CONF_PATH" <<EOL
cat >>"$NGINX_CONF_PATH" <<EOL
# http://${DOMAIN_NAME} redirect to https://${WWW_FQDN} # http://${DOMAIN_NAME} redirect to https://${WWW_FQDN}
server { server {
listen 80; listen 80;
@ -66,7 +77,7 @@ cat >>"$NGINX_CONF_PATH" <<EOL
EOL EOL
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# http://${WWW_FQDN} redirect to https://${WWW_FQDN} # http://${WWW_FQDN} redirect to https://${WWW_FQDN}
server { server {
listen 80; listen 80;
@ -77,9 +88,9 @@ cat >>"$NGINX_CONF_PATH" <<EOL
EOL EOL
# nextcloud http-to-https redirect # nextcloud http-to-https redirect
if [ "$DEPLOY_NEXTCLOUD" = true ]; then if [ "$DEPLOY_NEXTCLOUD" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# http://${NEXTCLOUD_FQDN} redirect to https://${NEXTCLOUD_FQDN} # http://${NEXTCLOUD_FQDN} redirect to https://${NEXTCLOUD_FQDN}
server { server {
listen 80; listen 80;
@ -89,11 +100,11 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
EOL EOL
fi fi
# gitea http to https redirect. # gitea http to https redirect.
if [ "$DEPLOY_GITEA" = true ]; then if [ "$DEPLOY_GITEA" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# http://${GITEA_FQDN} redirect to https://${GITEA_FQDN} # http://${GITEA_FQDN} redirect to https://${GITEA_FQDN}
server { server {
listen 80; listen 80;
@ -103,10 +114,10 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
EOL EOL
fi fi
# REDIRECT FOR BTCPAY_USER_FQDN # REDIRECT FOR BTCPAY_USER_FQDN
if [ "$VPS_HOSTING_TARGET" = lxd ]; then if [ "$VPS_HOSTING_TARGET" = lxd ]; then
# gitea http to https redirect. # gitea http to https redirect.
if [ "$DEPLOY_BTCPAY_SERVER" = true ]; then if [ "$DEPLOY_BTCPAY_SERVER" = true ]; then
@ -122,10 +133,12 @@ if [ "$VPS_HOSTING_TARGET" = lxd ]; then
EOL EOL
fi fi
fi fi
# TLS config for ghost.
cat >>"$NGINX_CONF_PATH" <<EOL if [ "$iteration" = 0 ]; then
# TLS config for ghost.
cat >>"$NGINX_CONF_PATH" <<EOL
# global TLS settings # global TLS settings
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.3; ssl_protocols TLSv1.3;
@ -143,34 +156,42 @@ cat >>"$NGINX_CONF_PATH" <<EOL
server { server {
listen 443 default_server; listen 443 default_server;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
return 403; return 403;
} }
# maybe helps with Twitter cards. # maybe helps with Twitter cards.
map \$http_user_agent \$og_prefix { #map \$http_user_agent \$og_prefix {
~*(googlebot|twitterbot)/ /open-graph; # ~*(googlebot|twitterbot)/ /open-graph;
} #}
EOL
fi
# https://${DOMAIN_NAME} redirect to https://${FQDN} cat >>"$NGINX_CONF_PATH" <<EOL
# https://${DOMAIN_NAME} redirect to https://${WWW_FQDN}
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
server_name ${DOMAIN_NAME}; server_name ${DOMAIN_NAME};
EOL # catch all; send request to ${WWW_FQDN}
########################################### location / {
return 301 https://${WWW_FQDN}\$request_uri;
}
if [ "$DEPLOY_NOSTR" = true ]; then EOL
cat >>"$NGINX_CONF_PATH" <<EOL
if [ "$DEPLOY_NOSTR" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL
# We return a JSON object with name/pubkey mapping per NIP05. # We return a JSON object with name/pubkey mapping per NIP05.
# https://www.reddit.com/r/nostr/comments/rrzk76/nip05_mapping_usernames_to_dns_domains_by_fiatjaf/sssss # https://www.reddit.com/r/nostr/comments/rrzk76/nip05_mapping_usernames_to_dns_domains_by_fiatjaf/sssss
# TODO I'm not sure about the security of this Access-Control-Allow-Origin. Read up and restrict it if possible. # TODO I'm not sure about the security of this Access-Control-Allow-Origin. Read up and restrict it if possible.
@ -181,34 +202,26 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
EOL EOL
fi fi
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# catch all; send request to ${WWW_FQDN}
location / {
return 301 https://${WWW_FQDN}\$request_uri;
}
EOL
#####################################################
cat >>"$NGINX_CONF_PATH" <<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 if [ "$ENABLE_NGINX_CACHING" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# main TLS listener; proxies requests to ghost service. NGINX configured to cache # 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; proxy_cache_path /tmp/nginx_ghost levels=1:2 keys_zone=ghostcache:600m max_size=100m inactive=24h;
EOL EOL
fi 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.
if [ "$DEPLOY_BTCPAY_SERVER" = true ]; then if [ "$DEPLOY_BTCPAY_SERVER" = true ]; then
@ -218,9 +231,9 @@ if [ "$VPS_HOSTING_TARGET" = lxd ]; then
listen 443 ssl http2; listen 443 ssl http2;
ssl on; ssl on;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
server_name ${BTCPAY_USER_FQDN}; server_name ${BTCPAY_USER_FQDN};
@ -241,41 +254,33 @@ if [ "$VPS_HOSTING_TARGET" = lxd ]; then
EOL EOL
fi fi
fi fi
# the open server block for the HTTPS listener # the open server block for the HTTPS listener
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
server_name ${WWW_FQDN}; server_name ${WWW_FQDN};
EOL EOL
# add the Onion-Location header if specifed. # add the Onion-Location header if specifed.
if [ "$DEPLOY_ONION_SITE" = true ]; then if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
add_header Onion-Location https://${ONION_ADDRESS}\$request_uri; add_header Onion-Location https://${ONION_ADDRESS}\$request_uri;
EOL EOL
fi fi
if [ "$ENABLE_NGINX_CACHING" = true ]; then if [ "$ENABLE_NGINX_CACHING" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# No cache + keep cookies for admin and previews # No cache + keep cookies for admin and previews
location ~ ^/(ghost/|p/|private/) { location ~ ^/(ghost/|p/|private/) {
@ -284,14 +289,14 @@ cat >>"$NGINX_CONF_PATH" <<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:2368; proxy_pass http://ghost-${iteration}:2368;
} }
EOL EOL
fi fi
# proxy config for ghost # proxy config for ghost
cat >>"$NGINX_CONF_PATH" <<EOL 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;
@ -306,11 +311,11 @@ cat >>"$NGINX_CONF_PATH" <<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:2368; proxy_pass http://ghost-${iteration}:2368;
EOL EOL
if [ "$ENABLE_NGINX_CACHING" = true ]; then if [ "$ENABLE_NGINX_CACHING" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL 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;
@ -338,10 +343,10 @@ cat >>"$NGINX_CONF_PATH" <<EOL
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 EOL
fi fi
# this is the closing location / block for the ghost HTTPS segment # this is the closing location / block for the ghost HTTPS segment
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
} }
EOL EOL
@ -354,19 +359,19 @@ 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:2368\$og_prefix\$request_uri; # proxy_pass http://ghost-${iteration}::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 # tor config
if [ "$DEPLOY_ONION_SITE" = true ]; then if [ "$DEPLOY_ONION_SITE" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# server listener for tor v3 onion endpoint # server listener for tor v3 onion endpoint
server { server {
listen 443 ssl http2; listen 443 ssl http2;
@ -385,18 +390,18 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
} }
EOL EOL
fi fi
if [ "$DEPLOY_NEXTCLOUD" = true ]; then if [ "$DEPLOY_NEXTCLOUD" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# TLS listener for ${NEXTCLOUD_FQDN} # TLS listener for ${NEXTCLOUD_FQDN}
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_certificate $CONTAINER_TLS_PATH/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem; ssl_certificate_key $CONTAINER_TLS_PATH/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem; ssl_trusted_certificate $CONTAINER_TLS_PATH/fullchain.pem;
server_name ${NEXTCLOUD_FQDN}; server_name ${NEXTCLOUD_FQDN};
@ -422,11 +427,12 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
} }
EOL EOL
fi
fi
if [ "$DEPLOY_GITEA" = true ]; then if [ "$DEPLOY_GITEA" = true ]; then
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL
# TLS listener for ${GITEA_FQDN} # TLS listener for ${GITEA_FQDN}
server { server {
listen 443 ssl http2; listen 443 ssl http2;
@ -447,7 +453,10 @@ cat >>"$NGINX_CONF_PATH" <<EOL
} }
} }
EOL EOL
fi fi
iteration=$((iteration+1))
done
# add the closing brace. # add the closing brace.
cat >>"$NGINX_CONF_PATH" <<EOL cat >>"$NGINX_CONF_PATH" <<EOL

18
domain_env.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
set -ex
# TODO, ensure VPS_HOSTING_TARGET is in range.
export NEXTCLOUD_FQDN="$NEXTCLOUD_HOSTNAME.$DOMAIN_NAME"
export BTCPAY_FQDN="$BTCPAY_HOSTNAME.$DOMAIN_NAME"
export BTCPAY_USER_FQDN="$BTCPAY_HOSTNAME_IN_CERT.$DOMAIN_NAME"
export WWW_FQDN="$WWW_HOSTNAME.$DOMAIN_NAME"
export GITEA_FQDN="$GITEA_HOSTNAME.$DOMAIN_NAME"
export NOSTR_FQDN="$NOSTR_HOSTNAME.$DOMAIN_NAME"
export ADMIN_ACCOUNT_USERNAME="info"
export CERTIFICATE_EMAIL_ADDRESS="$ADMIN_ACCOUNT_USERNAME@$DOMAIN_NAME"
export REMOTE_NEXTCLOUD_PATH="$REMOTE_HOME/nextcloud"
export REMOTE_GITEA_PATH="$REMOTE_HOME/gitea"
export BTC_CHAIN="$BTC_CHAIN"
export WWW_INSTANCE_TYPE="$WWW_INSTANCE_TYPE"
export BTCPAY_ADDITIONAL_HOSTNAMES="$BTCPAY_ADDITIONAL_HOSTNAMES"

View File

@ -2,20 +2,23 @@
set -x set -x
CLUSTER_NAME="development"
SSH_ENDPOINT_HOSTNAME="atlantis" SSH_ENDPOINT_HOSTNAME="atlantis"
SSH_ENDPOINT_DOMAIN_NAME="ancapistan.io" SSH_ENDPOINT_DOMAIN_NAME="ancapistan.io"
TEST_DOMAIN="ancapistan.casa" TEST_DOMAIN="ancapistan.casa"
CLUSTER_NAME="development"
export LXD_VM_NAME="${TEST_DOMAIN//./-}" export LXD_VM_NAME="${TEST_DOMAIN//./-}"
lxc delete --force www-"$LXD_VM_NAME" if [ -n "$TEST_DOMAIN" ]; then
lxc delete --force btcpay-"$LXD_VM_NAME" lxc delete --force www-"$LXD_VM_NAME"
lxc delete --force sovereign-stack lxc delete --force btcpay-"$LXD_VM_NAME"
lxc delete --force sovereign-stack-base lxc delete --force sovereign-stack
lxc delete --force sovereign-stack-base
lxc profile delete www-"$LXD_VM_NAME"
lxc profile delete btcpay-"$LXD_VM_NAME"
fi
lxc profile delete www-"$LXD_VM_NAME"
lxc profile delete btcpay-"$LXD_VM_NAME"
lxc profile delete sovereign-stack lxc profile delete sovereign-stack
lxc image rm sovereign-stack-base lxc image rm sovereign-stack-base
@ -30,6 +33,7 @@ lxc remote remove "$CLUSTER_NAME"
source "$HOME/.bashrc" source "$HOME/.bashrc"
./cluster.sh create "$CLUSTER_NAME" "$SSH_ENDPOINT_HOSTNAME.$SSH_ENDPOINT_DOMAIN_NAME" --data-plane-interface=enp89s0 ./cluster.sh create "$CLUSTER_NAME" "$SSH_ENDPOINT_HOSTNAME.$SSH_ENDPOINT_DOMAIN_NAME"
#--data-plane-interface=enp89s0
#./deploy.sh #./deploy.sh

22
reset_env.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
set -ex
export DOMAIN_NAME=
export DUPLICITY_BACKUP_PASSPHRASE=
export BTCPAY_HOSTNAME_IN_CERT=
export DEPLOY_GHOST=true
export DEPLOY_NEXTCLOUD=true
export DEPLOY_NOSTR=false
export NOSTR_ACCOUNT_PUBKEY=
export DEPLOY_GITEA=false
export DEPLOY_ONION_SITE=false
export GHOST_MYSQL_PASSWORD=
export GHOST_MYSQL_ROOT_PASSWORD=
export NEXTCLOUD_MYSQL_PASSWORD=
export NEXTCLOUD_MYSQL_ROOT_PASSWORD=
export GITEA_MYSQL_PASSWORD=
export GITEA_MYSQL_ROOT_PASSWORD=
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "$SCRIPT_DIR/defaults.sh"