From ed53d71b16bfb0e40862eea708164040a7fad17e Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Sat, 4 Sep 2021 09:27:05 -0500 Subject: [PATCH] Add backup / restore scripts --- .gitignore | 2 +- server/.s3cfg | 6 +++ server/backup.sh | 20 ++++++++++ server/deploy.sh | 1 + server/deploy_hook.sh | 3 +- server/download_database.sh | 19 +++++++++ .../{deploy.conf.example => hmn.conf.example} | 1 + server/restore_static_files.sh | 12 ++++++ server/root.Makefile | 16 +++++--- server/serversetup.sh | 40 +++++++++++++++---- 10 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 server/.s3cfg create mode 100755 server/backup.sh create mode 100755 server/download_database.sh rename server/{deploy.conf.example => hmn.conf.example} (63%) create mode 100755 server/restore_static_files.sh diff --git a/.gitignore b/.gitignore index db6e3cf..c6214fb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,6 @@ cinera/*/ cinera/cinera.conf annotations/ /hmn -deploy.conf +hmn.conf adminmailer/config.go adminmailer/adminmailer diff --git a/server/.s3cfg b/server/.s3cfg new file mode 100644 index 0000000..c1b5b6d --- /dev/null +++ b/server/.s3cfg @@ -0,0 +1,6 @@ +[default] +access_key = +secret_key = +host_base = nyc3.digitaloceanspaces.com +host_bucket = %(bucket)s.nyc3.digitaloceanspaces.com +use_https = True diff --git a/server/backup.sh b/server/backup.sh new file mode 100755 index 0000000..6e4bb16 --- /dev/null +++ b/server/backup.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -euxo pipefail +source /home/hmn/hmn/server/hmn.conf + +TS=$(date --iso-8601) +FILENAME="hmn_pg_dump_${HMN_ENV}_${TS}" +DUMP="/tmp/$FILENAME" + +echo "Dumping database..." +su - postgres -c "pg_dump -Fc hmn > $DUMP" + +echo "Uploading database..." +s3cmd --config /home/hmn/.s3cfg put $DUMP s3://hmn-backup/db/$FILENAME + +echo "Uploading static assets..." +s3cmd --config /home/hmn/.s3cfg sync /home/hmn/hmn/public/media/ s3://hmn-backup/static/media/ + +echo "Done." +rm "$DUMP" diff --git a/server/deploy.sh b/server/deploy.sh index 7a14074..24d8f49 100755 --- a/server/deploy.sh +++ b/server/deploy.sh @@ -1,6 +1,7 @@ #!/bin/bash set -eo pipefail +source /home/hmn/hmn/server/hmn.conf branch=$1 if [ -z "$branch" ]; then diff --git a/server/deploy_hook.sh b/server/deploy_hook.sh index e6154ac..7037bfc 100755 --- a/server/deploy_hook.sh +++ b/server/deploy_hook.sh @@ -1,8 +1,7 @@ #!/bin/bash set -eo pipefail - -. /home/hmn/hmn/server/deploy.conf +source /home/hmn/hmn/server/hmn.conf echo 'Content-Type: text/plain' echo '' diff --git a/server/download_database.sh b/server/download_database.sh new file mode 100755 index 0000000..d27f126 --- /dev/null +++ b/server/download_database.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Downloads a database backup from DigitalOcean. Does not restore it on its own; we have the +# seedfile command for that. + +set -euo pipefail +source /home/hmn/hmn/server/hmn.conf + +s3cmd --config /home/hmn/.s3cfg ls s3://hmn-backup/db/ + +echo "" +echo "Above is a list of all the available database backups." +echo "Enter the name of the one you would like to download (e.g. \"hmn_pg_dump_live_2021-09-01\"):" +read filename + +s3cmd --config /home/hmn/.s3cfg get s3://hmn-backup/db/$filename $filename + +echo "" +echo "Downloaded $filename to $(pwd)." diff --git a/server/deploy.conf.example b/server/hmn.conf.example similarity index 63% rename from server/deploy.conf.example rename to server/hmn.conf.example index 8bb0ce7..26602a8 100644 --- a/server/deploy.conf.example +++ b/server/hmn.conf.example @@ -1 +1,2 @@ +export HMN_ENV= export GITLAB_SECRET= diff --git a/server/restore_static_files.sh b/server/restore_static_files.sh new file mode 100755 index 0000000..ed36d93 --- /dev/null +++ b/server/restore_static_files.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -eo pipefail +source /home/hmn/hmn/server/hmn.conf + +if [ "$(whoami)" != "hmn" ]; then + echo "WARNING! You are not running this script as the hmn user. This will probably screw up file permissions." + echo "Press Ctrl-C to cancel, or press enter to continue." + read +fi + +s3cmd sync s3://hmn-backup/static/media/ /home/hmn/hmn/public/media/ diff --git a/server/root.Makefile b/server/root.Makefile index d46af60..9c5a982 100644 --- a/server/root.Makefile +++ b/server/root.Makefile @@ -11,13 +11,13 @@ help: ## Print this help. | sed 's/^.*\/\(.*\)/\1/' \ | awk 'BEGIN {FS = ":[^:]*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -deploy: - /home/hmn/hmn/server/deploy.sh $1 +deploy: ## Manually build and deploy a branch of the website. + /home/hmn/hmn/server/deploy.sh -build: - sudo -u hmn --preserve-env=PATH bash -c "cd ~/hmn && go build -o /home/hmn/bin/hmn src/main.go" +build: ## Rebuild the website binary + sudo -u hmn --preserve-env=PATH bash -c "cd ~/hmn && go build -o /home/hmn/bin/hmn src/main.go" -edit-config: +edit-config: ## Edit the website config vim /home/hmn/hmn/src/config/config.go @echo 'Now that you have edited the config, you probably want to re-deploy the site:' @echo '' @@ -29,3 +29,9 @@ logs: ## View logs for the website logs-caddy: ## View logs for Caddy journalctl -u caddy.service -f + +download-database: ## Download a database backup + sudo -u hmn bash -c "cd ~ && ~/hmn/server/download_database.sh" + +restore-static-files: ## Download static files from the backup. + sudo -u hmn bash -c "cd ~/hmn && /home/hmn/hmn/server/restore_static_files.sh" diff --git a/server/serversetup.sh b/server/serversetup.sh index 025a307..1364234 100755 --- a/server/serversetup.sh +++ b/server/serversetup.sh @@ -61,7 +61,8 @@ if [ $checkpoint -lt 30 ]; then apt update apt install -y \ build-essential \ - libcurl4-openssl-dev byacc flex + libcurl4-openssl-dev byacc flex \ + s3cmd savecheckpoint 30 fi @@ -205,12 +206,16 @@ if [ $checkpoint -lt 100 ]; then cp /home/hmn/hmn/server/logrotate /etc/logrotate.d/hmn cp /home/hmn/hmn/src/config/config.go.example /home/hmn/hmn/src/config/config.go - cp /home/hmn/hmn/server/deploy.conf.example /home/hmn/hmn/server/deploy.conf + cp /home/hmn/hmn/server/hmn.conf.example /home/hmn/hmn/server/hmn.conf cp /home/hmn/hmn/cinera/cinera.conf.sample /home/hmn/hmn/cinera/cinera.conf chown hmn:hmn /home/hmn/hmn/src/config/config.go - chown hmn:hmn /home/hmn/hmn/server/deploy.conf + chown hmn:hmn /home/hmn/hmn/server/hmn.conf chown hmn:hmn /home/hmn/hmn/cinera/cinera.conf + cp /home/hmn/hmn/server/.s3cfg /home/hmn/.s3cfg + chown hmn:hmn /home/hmn/.s3cfg + chmod 600 /home/hmn/.s3cfg + cp /home/hmn/hmn/server/root.Makefile /root/Makefile systemctl daemon-reload @@ -218,6 +223,14 @@ if [ $checkpoint -lt 100 ]; then savecheckpoint 100 fi +# Set up crons +if [ $checkpoint -lt 105 ]; then + # See https://stackoverflow.com/a/9625233/1177139 + (crontab -l 2>/dev/null; echo "50 4 * * * /home/hmn/hmn/server/backup.sh") | crontab - + + savecheckpoint 105 +fi + # Build the site for the first time (despite bad config) if [ $checkpoint -lt 110 ]; then do_as hmn <<'SCRIPT' @@ -272,20 +285,24 @@ ${BLUE_BOLD}Website${RESET}: /home/hmn/hmn/src/config/config.go You don't need to deploy the site yet; wait until you've configured everything. -${BLUE_BOLD}Deploy Secret${RESET}: /home/hmn/hmn/server/deploy.conf +${BLUE_BOLD}HMN Environment Vars${RESET}: /home/hmn/hmn/server/hmn.conf First, go to GitLab and add a webhook with a secret. Set it to trigger on push events for the branch you are using for deploys. https://git.handmade.network/hmn/hmn/hooks - Then, edit the above file and fill in the secret value from the - GitLab webhook. + Then, edit the above file and fill in all the environment vars, including + the secret value from the GitLab webhook. ${BLUE_BOLD}Cinera${RESET}: /home/hmn/hmn/cinera/cinera.conf Add the correct domain. +${BLUE_BOLD}s3cmd${RESET}: /home/hmn/.s3cfg + + Add the DigitalOcean Spaces credentials, and ensure that the bucket info is correct. + ${BLUE_BOLD}===== Next steps =====${RESET} @@ -293,11 +310,18 @@ Make sure you have everything on your path: source ~/.bashrc -Restore a database backup: +Download and restore a database backup: + + make download-database su hmn cd ~ - hmn seedfile + hmn migrate --list + hmn seedfile + +Restore static files: + + make restore-static-files Start up Caddy: