From 8d0af43339c693d1c99c88584a22c34ed7d55f54 Mon Sep 17 00:00:00 2001 From: Derek Smith Date: Fri, 9 Sep 2022 14:00:07 -0400 Subject: [PATCH] More work on self-hosting + projects. --- cluster.sh | 46 ++- defaults.sh | 16 +- deploy.sh | 211 +++++------- deployment/btcpayserver/go.sh | 7 +- deployment/deploy_vms.sh | 2 +- deployment/provision_vps.sh | 6 +- deployment/www/backup.sh | 6 +- deployment/www/generate_certs.sh | 42 ++- deployment/www/go.sh | 214 +++++++------ deployment/www/restore.sh | 8 +- deployment/www/stub_docker_yml.sh | 516 ++++++++++++++++-------------- deployment/www/stub_nginxconf.sh | 233 +++++++------- domain_env.sh | 18 ++ reset.sh | 20 +- reset_env.sh | 22 ++ 15 files changed, 720 insertions(+), 647 deletions(-) create mode 100755 domain_env.sh create mode 100755 reset_env.sh diff --git a/cluster.sh b/cluster.sh index fcf70be..6ce1707 100755 --- a/cluster.sh +++ b/cluster.sh @@ -35,16 +35,14 @@ if [ "$COMMAND" = create ]; then cat >"$CLUSTER_DEFINITION" <> "$CLUSTER_PATH/authorized_keys" 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 " with your ssh pubkey at '$HOME/.ssh/id_rsa.pub'." + echo " Add ssh pubkeys for your various management machines, if any." + echo " By default we added your main ssh pubkey: '$HOME/.ssh/id_rsa.pub'." exit 1 fi @@ -214,7 +215,6 @@ function new_pass { function instantiate_vms { export VPS_HOSTING_TARGET="$VPS_HOSTING_TARGET" - export RUN_CERT_RENEWAL="$RUN_CERT_RENEWAL" export BTC_CHAIN="$BTC_CHAIN" export UPDATE_BTCPAY="$UPDATE_BTCPAY" export RECONFIGURE_BTCPAY_SERVER="$RECONFIGURE_BTCPAY_SERVER" @@ -227,12 +227,9 @@ function instantiate_vms { FQDN= 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 ./domain_env.sh # VALIDATE THE INPUT from the ENVFILE if [ -z "$DOMAIN_NAME" ]; then @@ -240,34 +237,10 @@ function instantiate_vms { exit 1 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 # 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. - 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}')" DATA_PLANE_MACVLAN_INTERFACE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f2)" DISK_TO_USE="$(echo "$CONFIG_ITEMS" | cut -d ',' -f3)" @@ -286,29 +259,13 @@ function instantiate_vms { export MAC_ADDRESS_TO_PROVISION= export VPS_HOSTNAME="$VPS_HOSTNAME" 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. if [ -z "$SOVEREIGN_STACK_MAC_ADDRESS" ]; then echo "ERROR: SOVEREIGN_STACK_MAC_ADDRESS is undefined. Check your project definition." exit 1 fi - if [ ! -d "$LOCAL_BACKUP_PATH" ]; then - mkdir -p "$LOCAL_BACKUP_PATH" - BACKUP_PATH_CREATED=true - fi - DDNS_HOST= MIGRATE_VPS=false if [ "$VIRTUAL_MACHINE" = www ]; then @@ -317,7 +274,7 @@ function instantiate_vms { fi VPS_HOSTNAME="$WWW_HOSTNAME" - MAC_ADDRESS_TO_PROVISION="$WWW_MAC_ADDRESS" + MAC_ADDRESS_TO_PROVISION="$WWW_SERVER_MAC_ADDRESS" DDNS_HOST="$WWW_HOSTNAME" ROOT_DISK_SIZE_GB="$((ROOT_DISK_SIZE_GB + NEXTCLOUD_SPACE_GB))" if [ "$MIGRATE_WWW" = true ]; then @@ -330,7 +287,7 @@ function instantiate_vms { DDNS_HOST="$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 ROOT_DISK_SIZE_GB=150 elif [ "$BTC_CHAIN" = testnet ]; then @@ -352,8 +309,25 @@ function instantiate_vms { export DDNS_HOST="$DDNS_HOST" export FQDN="$DDNS_HOST.$DOMAIN_NAME" 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 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. if [ "$VPS_HOSTING_TARGET" = aws ]; then @@ -383,7 +357,8 @@ function instantiate_vms { fi # 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 # delete the remote VPS. @@ -411,7 +386,8 @@ function instantiate_vms { fi else 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 # The machine does not exist. Let's bring it into existence, restoring from latest backup. @@ -419,40 +395,24 @@ function instantiate_vms { ./deployment/deploy_vms.sh fi + # if the local docker client isn't logged in, do so; + # this helps prevent docker pull errors since they throttle. + if [ ! -f "$HOME/.docker/config.json" ]; then + echo "$REGISTRY_PASSWORD" | docker login --username "$REGISTRY_USERNAME" --password-stdin + fi + + # this tells our local docker client to target the remote endpoint via SSH + 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 done } -function run_domain { - - # if the local docker client isn't logged in, do so; - # this helps prevent docker pull errors since they throttle. - if [ ! -f "$HOME/.docker/config.json" ]; then - echo "$REGISTRY_PASSWORD" | docker login --username "$REGISTRY_USERNAME" --password-stdin - fi - - # this tells our local docker client to target the remote endpoint via SSH - export DOCKER_HOST="ssh://ubuntu@$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. - if docker info | grep -q "Swarm: inactive"; then - docker swarm init --advertise-addr enp6s0 - fi - - bash -c "./deployment/btcpayserver/go.sh" - - echo "Successfully deployed '$DOMAIN_NAME' with git commit '$(cat ./.git/refs/heads/master)' VPS_HOSTING_TARGET=$VPS_HOSTING_TARGET;" - -} function stub_site_definition { mkdir -p "$SITE_PATH" "$PROJECT_PATH/sites" @@ -471,36 +431,21 @@ function stub_site_definition { cat >"$SITE_DEFINITION_PATH" <"$PROJECT_DEFINITION_PATH" < /dev/null 2>&1 + if wait-for-it -t 5 "$PRIMARY_WWW_FQDN:80"; then + xdg-open "http://$PRIMARY_WWW_FQDN" > /dev/null 2>&1 fi else if wait-for-it -t 5 "$FQDN:443"; then diff --git a/deployment/deploy_vms.sh b/deployment/deploy_vms.sh index 414090e..4fa04fa 100755 --- a/deployment/deploy_vms.sh +++ b/deployment/deploy_vms.sh @@ -60,7 +60,7 @@ elif [ "$VPS_HOSTING_TARGET" = lxd ]; then # create a base image if needed and instantiate a VM. 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." exit 1 fi diff --git a/deployment/provision_vps.sh b/deployment/provision_vps.sh index 1d65494..5d8b551 100755 --- a/deployment/provision_vps.sh +++ b/deployment/provision_vps.sh @@ -47,9 +47,8 @@ if [ "$VIRTUAL_MACHINE" = www ] || [ "$VIRTUAL_MACHINE" = certonly ]; then --amazonec2-ami "$AWS_AMI_ID" \ --amazonec2-root-size "$ROOT_DISK_SIZE_GB" \ --amazonec2-instance-type "$WWW_INSTANCE_TYPE" \ - --engine-label commit="$LATEST_GIT_COMMIT" \ "$FQDN" - + # --engine-label commit="$LATEST_GIT_COMMIT" \ elif [ "$VIRTUAL_MACHINE" = btcpayserver ]; then # creates a public VM in AWS and provisions the bcm website. docker-machine create --driver amazonec2 \ @@ -62,9 +61,8 @@ elif [ "$VIRTUAL_MACHINE" = btcpayserver ]; then --amazonec2-ami "$AWS_AMI_ID" \ --amazonec2-root-size "$ROOT_DISK_SIZE_GB" \ --amazonec2-instance-type "$BTCPAY_INSTANCE_TYPE" \ - --engine-label commit="$LATEST_GIT_COMMIT" \ "$FQDN" - +# --engine-label commit="$LATEST_GIT_COMMIT" \ fi docker-machine scp "$CLUSTER_PATH/authorized_keys" "$FQDN:$REMOTE_HOME/authorized_keys" diff --git a/deployment/www/backup.sh b/deployment/www/backup.sh index 7b71dbf..59cb5ce 100755 --- a/deployment/www/backup.sh +++ b/deployment/www/backup.sh @@ -9,12 +9,12 @@ cd "$(dirname "$0")" # 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. -ssh "$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 PASSPHRASE="$DUPLICITY_BACKUP_PASSPHRASE" duplicity --allow-source-mismatch --exclude "$REMOTE_HOME/backups" "$REMOTE_HOME" "file://$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. # 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 -av "$SSHFS_PATH/" "$LOCAL_BACKUP_PATH/" diff --git a/deployment/www/generate_certs.sh b/deployment/www/generate_certs.sh index 1cb06b0..19329fd 100755 --- a/deployment/www/generate_certs.sh +++ b/deployment/www/generate_certs.sh @@ -2,6 +2,7 @@ set -ex + # let's do a refresh of the certificates. Let's Encrypt will not run if it's not time. docker pull certbot/certbot:latest @@ -20,13 +21,38 @@ if [ "$VPS_HOSTING_TARGET" = aws ]; 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 # 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 "$WWW_FQDN" -d "$BTCPAY_USER_FQDN" -d "$NEXTCLOUD_FQDN" -d "$GITEA_FQDN" -d "$NOSTR_FQDN" --email "$CERTIFICATE_EMAIL_ADDRESS" + # 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 \ + --name certbot \ + -p 80:80 \ + -p 443:443 \ + -v "$REMOTE_HOME/letsencrypt/$DOMAIN_NAME":/etc/letsencrypt \ + -v /var/lib/letsencrypt:/var/lib/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" + + done fi diff --git a/deployment/www/go.sh b/deployment/www/go.sh index d9fda0b..57c6163 100755 --- a/deployment/www/go.sh +++ b/deployment/www/go.sh @@ -1,94 +1,109 @@ #!/bin/bash -set -exuo +set -exu cd "$(dirname "$0")" -if [ "$DEPLOY_GHOST" = true ]; then - if [ -z "$GHOST_MYSQL_PASSWORD" ]; then - echo "ERROR: Ensure GHOST_MYSQL_PASSWORD is configured in your site_definition." - exit 1 - fi - - if [ -z "$GHOST_MYSQL_ROOT_PASSWORD" ]; then - echo "ERROR: Ensure GHOST_MYSQL_ROOT_PASSWORD is configured in your site_definition." - exit 1 - fi -fi - -if [ "$DEPLOY_GITEA" = true ]; then - if [ -z "$GITEA_MYSQL_PASSWORD" ]; then - echo "ERROR: Ensure GITEA_MYSQL_PASSWORD is configured in your site_definition." - exit 1 - fi - if [ -z "$GITEA_MYSQL_ROOT_PASSWORD" ]; then - echo "ERROR: Ensure GITEA_MYSQL_ROOT_PASSWORD is configured in your site_definition." - exit 1 - fi -fi - -if [ "$DEPLOY_NEXTCLOUD" = true ]; then - if [ -z "$NEXTCLOUD_MYSQL_ROOT_PASSWORD" ]; then - echo "ERROR: Ensure NEXTCLOUD_MYSQL_ROOT_PASSWORD is configured in your site_definition." - exit 1 - fi - - if [ -z "$NEXTCLOUD_MYSQL_PASSWORD" ]; then - echo "ERROR: Ensure NEXTCLOUD_MYSQL_PASSWORD is configured in your site_definition." - exit 1 - fi -fi - -if [ "$DEPLOY_NOSTR" = true ]; then - if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then - echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." - exit 1 - fi - - if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then - echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." - exit 1 - fi -fi - -if [ -z "$DUPLICITY_BACKUP_PASSPHRASE" ]; then - echo "ERROR: Ensure DUPLICITY_BACKUP_PASSPHRASE is configured in your site_definition." - exit 1 -fi - -if [ -z "$DOMAIN_NAME" ]; then - echo "ERROR: Ensure DOMAIN_NAME is configured in your site_definition." - exit 1 -fi - -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 "INFO: Go to your site_definition file and set the NOSTR_ACCOUNT_PUBKEY variable." - exit 1 -fi - +# Create the nginx config file which covers all domains. bash -c ./stub_nginxconf.sh -TOR_CONFIG_PATH= +# redirect all docker commands to the remote host. +export DOCKER_HOST="ssh://ubuntu@$PRIMARY_WWW_FQDN" -ssh "$WWW_FQDN" mkdir -p "$REMOTE_HOME/ghost_site" "$REMOTE_HOME/ghost_db" +for DOMAIN_NAME in ${DOMAIN_LIST//,/ }; do + export DOMAIN_NAME="$DOMAIN_NAME" + export SITE_PATH="$SITES_PATH/$DOMAIN_NAME" -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 + # source the site path so we know what features it has. + source ../../reset_env.sh + source "$SITE_PATH/site_definition" + source ../../domain_env.sh -if [ "$DEPLOY_GITEA" = true ]; then - ssh "$FQDN" "mkdir -p $REMOTE_GITEA_PATH/data $REMOTE_GITEA_PATH/db" -fi + ### Let's check to ensure all the requiredsettings are set. + if [ "$DEPLOY_GHOST" = true ]; then + if [ -z "$GHOST_MYSQL_PASSWORD" ]; then + echo "ERROR: Ensure GHOST_MYSQL_PASSWORD is configured in your site_definition." + exit 1 + fi + + if [ -z "$GHOST_MYSQL_ROOT_PASSWORD" ]; then + echo "ERROR: Ensure GHOST_MYSQL_ROOT_PASSWORD is configured in your site_definition." + exit 1 + fi + fi + + if [ "$DEPLOY_GITEA" = true ]; then + if [ -z "$GITEA_MYSQL_PASSWORD" ]; then + echo "ERROR: Ensure GITEA_MYSQL_PASSWORD is configured in your site_definition." + exit 1 + fi + if [ -z "$GITEA_MYSQL_ROOT_PASSWORD" ]; then + echo "ERROR: Ensure GITEA_MYSQL_ROOT_PASSWORD is configured in your site_definition." + exit 1 + fi + fi + + if [ "$DEPLOY_NEXTCLOUD" = true ]; then + if [ -z "$NEXTCLOUD_MYSQL_ROOT_PASSWORD" ]; then + echo "ERROR: Ensure NEXTCLOUD_MYSQL_ROOT_PASSWORD is configured in your site_definition." + exit 1 + fi + + if [ -z "$NEXTCLOUD_MYSQL_PASSWORD" ]; then + echo "ERROR: Ensure NEXTCLOUD_MYSQL_PASSWORD is configured in your site_definition." + exit 1 + fi + fi + + if [ "$DEPLOY_NOSTR" = true ]; then + if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then + echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." + exit 1 + fi + + if [ -z "$NOSTR_ACCOUNT_PUBKEY" ]; then + echo "ERROR: Ensure NOSTR_ACCOUNT_PUBKEY is configured in your site_definition." + exit 1 + fi + fi + + if [ -z "$DUPLICITY_BACKUP_PASSPHRASE" ]; then + echo "ERROR: Ensure DUPLICITY_BACKUP_PASSPHRASE is configured in your site_definition." + exit 1 + fi + + if [ -z "$DOMAIN_NAME" ]; then + echo "ERROR: Ensure DOMAIN_NAME is configured in your site_definition." + exit 1 + fi + + 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 "INFO: Go to your site_definition file and set the NOSTR_ACCOUNT_PUBKEY variable." + exit 1 + fi + + 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 + + if [ "$DEPLOY_GITEA" = true ]; then + ssh "$FQDN" "mkdir -p $REMOTE_GITEA_PATH/data $REMOTE_GITEA_PATH/db" + fi + +done + +### The next series of commands # 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 @@ -98,7 +113,10 @@ if [ "$RESTORE_WWW" = true ]; then # just created, we know that we'll deploy fresh. ./restore.sh else - ./generate_certs.sh + + if [ "$RUN_CERT_RENEWAL" = true ]; then + ./generate_certs.sh + 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. # this is how we generate a new torv3 endpoint. - if ! ssh "$WWW_FQDN" "[ -d $REMOTE_HOME/tor/www ]"; then - ssh "$WWW_FQDN" "mkdir -p $REMOTE_HOME/tor" + if ! ssh "$PRIMARY_WWW_FQDN" "[ -d $REMOTE_HOME/tor/www ]"; then + ssh "$PRIMARY_WWW_FQDN" "mkdir -p $REMOTE_HOME/tor" TOR_CONFIG_PATH="$(pwd)/tor/torrc-init" export TOR_CONFIG_PATH="$TOR_CONFIG_PATH" docker stack deploy -c ./tor.yml torstack @@ -118,37 +136,31 @@ if [ "$DEPLOY_ONION_SITE" = true ]; then sleep 20 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" # # 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 - # ssh "$WWW_FQDN" ln -s "$REMOTE_HOME/ghost_site/themes $REMOTE_HOME/tor_ghost/themes" + # if ! ssh "$PRIMARY_WWW_FQDN" "[ -L $REMOTE_HOME/tor_ghost ]"; then + # ssh "$PRIMARY_WWW_FQDN" ln -s "$REMOTE_HOME/ghost_site/themes $REMOTE_HOME/tor_ghost/themes" # 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 -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. -wait-for-it -t 320 "$WWW_FQDN:80" -wait-for-it -t 320 "$WWW_FQDN:443" +# # open bowser tabs. +# if [ "$DEPLOY_GHOST" = true ]; then +# xdg-open "http://$PRIMARY_WWW_FQDN" > /dev/null 2>&1 +# fi -# open bowser tabs. -if [ "$DEPLOY_GHOST" = true ]; then - xdg-open "http://$WWW_FQDN" > /dev/null 2>&1 -fi +# if [ "$DEPLOY_NEXTCLOUD" = true ]; then +# xdg-open "http://$NEXTCLOUD_FQDN" > /dev/null 2>&1 +# fi -if [ "$DEPLOY_NEXTCLOUD" = true ]; then - xdg-open "http://$NEXTCLOUD_FQDN" > /dev/null 2>&1 -fi - -if [ "$DEPLOY_GITEA" = true ]; then - xdg-open "http://$GITEA_FQDN" > /dev/null 2>&1 -fi -#fi +# if [ "$DEPLOY_GITEA" = true ]; then +# xdg-open "http://$GITEA_FQDN" > /dev/null 2>&1 +# fi +# #fi diff --git a/deployment/www/restore.sh b/deployment/www/restore.sh index 9cae660..3c6e65b 100755 --- a/deployment/www/restore.sh +++ b/deployment/www/restore.sh @@ -7,13 +7,13 @@ set -exu # 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. -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 -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. -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. -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/" diff --git a/deployment/www/stub_docker_yml.sh b/deployment/www/stub_docker_yml.sh index ba39d22..27a4dad 100755 --- a/deployment/www/stub_docker_yml.sh +++ b/deployment/www/stub_docker_yml.sh @@ -1,40 +1,119 @@ #!/bin/bash -set -eu +set -eux 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. -echo "" > "$DOCKER_YAML_PATH" +ssh "$PRIMARY_WWW_FQDN" sudo rm -rf /home/ubuntu/ghost +sleep 4 -cat >>"$DOCKER_YAML_PATH" < "$DOCKER_YAML_PATH" <> "$DOCKER_YAML_PATH" <> "$DOCKER_YAML_PATH" <> "$DOCKER_YAML_PATH" <> "$DOCKER_YAML_PATH" < "$DOCKER_YAML_PATH" + + cat >>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <>"$DOCKER_YAML_PATH" <