Backup and auto deployment .NET Core app on AWS Lightsail Linux instance

This is continuation of Running .NET Core app on AWS Lightsail Linux instance.

By this moment everything is working exactly as I want. But I have 2 things that really annoys me: backup and updating web site. Because I revoked access to web site directory for every account except www.example.com I have to run a lot of commands from sudo user to backup and update my web site. I would like to automate these steps.

Backup

I have 2 things to backup: web site itself and its data. I separate them because they have different update schedule. For example, I can update web site few times per day and then did not update it for weeks. Obviously, I would like to do backup before I update web site. Web site data should be backed up regularly.

Here is script to back just web site:

# Start
cd ~

CurrentDir=$(pwd)
BackupDir="$CurrentDir/Backup/Bin $(date '+%Y_%m_%d %H_%M_%S')"
echo "$BackupDir/"
mkdir -p "$BackupDir"
sudo rsync -r --exclude={'siteuploadfiles','nodb_storage'} "/var/www/www.example.com/" "$BackupDir/"

# Make sure we can delete it

sudo chown -R $USER: "$BackupDir"
sudo chmod -R 700 "$BackupDir"

As you can see it is quite simple. I set BackupDir variable. It will look like /home/user/Backup/Bin 2021_04_02 17_03_24.  Then I create that directory recursively. I am using standard rsync command and exclude siteuploadfiles and nodb_storage because they contain data. Then I take ownership for all files and directories in backup directory and set proper permissions for current user.

Here is script to backup web site data:

# Start
cd ~

CurrentDir=$(pwd)
BackupDir="$CurrentDir/Backup/Data $(date '+%Y_%m_%d %H_%M_%S')"
echo "$BackupDir/"
mkdir -p "$BackupDir"
sudo rsync -r --include='/' --include='/siteuploadfiles/***' --include '/nodb_storage/***' --exclude='*' "/var/www/www.example.com/" "$BackupDir"

# Make sure we can delete it
sudo chown -R $USER: "$BackupDir"
sudo chmod -R 700 "$BackupDir"

# Remove garbage
rm -r "$BackupDir/nodb_storage/projects/default"

zip -1 -r -q "$BackupDir.zip" "$BackupDir"

Everything is like previous script except that at the end I used zip command to compress all data. Data for my web site contains a lot of small files and transferring them is quite painful over high latency network. As result, I decided to compress them, and I can copy that zip file in few seconds instead of 10 minutes before.

Update

Next step to update web site. Here is batch file on Windows to prepare project:

rd ..\Publish\Current /s/q
del ..\Publish\Current.zip
dotnet publish -c Release -f netcoreapp3.1 -o ..\Publish\Current
"C:\Bin\7z\7za.exe" a -mmt8 -mx1 "..\Publish\Current.zip" ..\Publish\Current

It should be in project directory. Run it and then copy Current.zip to virtual PC and run this script:

# Change current directory
cd ~

CurrentDir=$(pwd)

# Delete previously deployed version
rm -R "$CurrentDir/Current/"

# Unzip new version
unzip -q Current.zip

# Enable maintenance
sudo mv /var/www/www.example.com/app_offline.htm_ /var/www/www.example.com/app_offline.htm

# Stop web site
sudo systemctl stop www.example.com

# Update to latest version
echo "$CurrentDir/Current/"
sudo rsync -r --delete -t -v --exclude={'siteuploadfiles','nodb_storage','app_offline.htm'} "$CurrentDir/Current/" "/var/www/www.example.com/"

# Folder ownership
sudo chown -R www.example.com: /var/www/www.example.com

# Folder and files permissions
sudo chmod -R 500 /var/www/www.example.com
sudo chmod -R 700 /var/www/www.example.com/nodb_storage
sudo chmod -R 700 /var/www/www.example.com/siteuploadfiles

# Specific permissions that I needed for maintenance
sudo chmod 555 /var/www/www.example.com
sudo chmod 544 /var/www/www.example.comb/app_offline.htm

# Remove maintenance flag
sudo mv /var/www/www.example.com/app_offline.htm /var/www/www.example.com/app_offline.htm_

# Start web site
sudo systemctl start www.example.com

As you can, script deleted directory named Current and then extract Current.zip. And it will create Current directory. Then we enable maintenance mode and stop dotnet command that is running our site. Then updating web site from Current directory and ignore directories siteuploadfiles, nodb_storage and file app_offline.htm. Then script applies ownership and permissions, start dotnet web site and disable maintenance mode.

Note: be really careful with rsync arguments. Presence or absence of slash at the end of path is quite critical.

After that I have automated backup and deploy.

I hope it helps someone.