Skip to content

Instantly share code, notes, and snippets.

@svale
Last active February 5, 2020 12:03
Show Gist options
  • Save svale/09ae5129e3d8f8263dc13056a45a7660 to your computer and use it in GitHub Desktop.
Save svale/09ae5129e3d8f8263dc13056a45a7660 to your computer and use it in GitHub Desktop.
Zero down time deployment script for static generate sites on forge
#!/bin/bash
set -e
# ./deploy/-deploy.sh
# Deployment with zero downtime
# Based on : https://gist.github.com/actionm/63b927a9b933e54414ae2857e5712162
# By default keeps 2 last deployments in KEEP_DEPLOYMENTS_DIR and current deployment
usage()
{
echo ""
echo "Usage: $0 -b branch -n projectName -d projectDir -k keepDeployments"
echo -e "\t-b Which git branch to deploy"
echo -e "\t-n Name of the project"
echo -e "\t-d Web direcotry"
echo -e "\t-k How many deployments to keep"
exit 1 # Exit script after printing help
}
# By default keeps 2 last deployments
keepDeployments=2
branch="master"
while getopts "hb:n:d:k:" opt
do
case "$opt" in
b ) branch="$OPTARG" ;;
n ) projectName="$OPTARG" ;;
d ) projectDir="$OPTARG" ;;
k ) keepDeployments="$OPTARG" ;;
h ) usage ;;
? ) usage ;; # Print usage in case parameter is non-existent
esac
done
# Print usage in case parameters are empty
if [ -z "$branch" ] || [ -z "$projectName" ] || [ -z "$projectDir" ] || [ -z "$keepDeployments" ]
then
echo "Some or all of the parameters are empty";
usage
fi
##### MAIN
# Branch
BRANCH=$branch
# Project domain
PROJECT_NAME=$projectName
# Project directory
PROJECT_DIR=$projectDir
# History to keep
KEEP_DEPLOYMENTS=$keepDeployments
# Deployments directory
KEEP_DEPLOYMENTS_DIR=/home/forge/deploy
DEPLOY_DIR_NAME=$(date +'%d%m%Y_%H%M%S')
DEPLOY_DIR_PROJECT=${KEEP_DEPLOYMENTS_DIR}/${PROJECT_NAME}
DEPLOY_DIR=${DEPLOY_DIR_PROJECT}/${DEPLOY_DIR_NAME}
echo "Initialize deployment directory '"${DEPLOY_DIR}"'"
[ -d ${DEPLOY_DIR} ] || mkdir -p ${DEPLOY_DIR}
# Importantly retains files outside repo - such as .env
echo "Copying '"${PROJECT_DIR}/"' to '"${DEPLOY_DIR}"'"
rsync -a $PROJECT_DIR/ $DEPLOY_DIR
echo "Execute commands in deployment directory"
cd ${DEPLOY_DIR}
# Update
git pull origin $BRANCH
yarn
yarn generate
# Atomic, zero downtime
echo "Update symlink '"${DEPLOY_DIR}"' to '"${PROJECT_DIR}.tmp"'"
ln -s $DEPLOY_DIR ${PROJECT_DIR}.tmp
# Remove current project directory if not symlink
if [ ! -h $PROJECT_DIR ]; then
rm -rf $PROJECT_DIR
fi
echo "Update symlink '"${DEPLOY_DIR}.tmp"' to '"${PROJECT_DIR}"'"
mv -Tf $PROJECT_DIR.tmp $PROJECT_DIR
echo "Clear old deployments in '"${DEPLOY_DIR_PROJECT}" keep last '"${KEEP_DEPLOYMENTS}"'"
cd ${DEPLOY_DIR_PROJECT}
rm -rf $(ls ${DEPLOY_DIR_PROJECT} -t | grep -v ${DEPLOY_DIR_NAME} | tail -n +$((KEEP_DEPLOYMENTS+1)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment