Skip to content

Instantly share code, notes, and snippets.

@eashish93
Last active November 17, 2017 21:02
Show Gist options
  • Save eashish93/1734fd68e00ac453e16922b84ce2d6c2 to your computer and use it in GitHub Desktop.
Save eashish93/1734fd68e00ac453e16922b84ce2d6c2 to your computer and use it in GitHub Desktop.
Deploy Script for My Node.JS app for zero-downtime (single server - no revert - only latest commit)
#!/bin/bash
## SEE: http://pm2.keymetrics.io/docs/tutorials/capistrano-like-deployments
# 0. Folder Structure
# -> /var/www/project_root
# -> source
# -> current -> symlink to latest release
# -> versions
# -> sha-of-commit
# -> logs
# -> config
# -> pm2c.json
# STEPS REQUIRED
# __Initial Requirement__ (do it manually everytime)
# 0. pm2, node must be installed.
# 1. git clone the project and change its name to source.
# 2. add .env file or other config.
# 3. do npm install first time only for caching.
## CASE-1: User want to deploy new commit (using deploy command)
# 1. cd into source dir and get the commit sha of version you want.
# 2. if (dir doesn't exist with same commit)
# -> create a new dir in project_root/versions, do npm prune & npm install & npm run build.
# -> delete last symlink and create new symlink to this version.
# 3. Manually do pm2 reload/restart/start appname.
## CASE-2: User want to revert (or want to redeploy to specific commit) NOT POSSIBLE CURRENTLY.
# 1. get the commit from source dir according to revert number or default 1.
# 2. perform steps from CASE-1.
## CASE-3: User changed the .env file in source dir.
# 1. first delete the whole versions folder and do deploy.
## COMMANDS
# 1. deploy: Simply deploy using the latest commit from source folder.
set -e;
ROOT_PATH=${1:-"/var/www/imgsquash.com"};
# latest_commit=$(git rev-parse --verify --short HEAD);
# nth_commit=$(git rev-parse --verify --short @{$2});
log() {
# ref: http://linuxcommand.org/lc3_adv_tput.php
# set color green and bold text.
tput bold; tput setaf 2; echo " ○ $@"; tput sgr0;
}
abort() {
echo
echo " $@" 1>&2
echo
exit 1
}
deploy() {
# deploy to the latest version.
local ref=$1; # args of this function.
local path=$ROOT_PATH;
log "deploying";
log "stashing all local changes if any";
cd $path/source && git stash -u;
test $? -eq 0 || abort stashed failed;
# Fetch source.
log "pulling updates";
cd $path/source && git pull --all;
test $? -eq 0 || abort pull failed;
# Get latest commit sha
log "getting latest sha commit";
local latest_sha=$(git rev-parse --short --verify HEAD);
# if directory doesn't exist
if ! [ -d "$path/versions/$latest_sha" ]; then
log "creating new sha dir on $path/versions"
mkdir -p $path/versions/$latest_sha;
test $? -eq 0 || abort directory created unsuccessful
# using rsync instead of cp for fast copy. Don't forget trailing slash.
rsync -aHW --stats $path/source/ $path/versions/$latest_sha;
test $? -eq 0 || abort copy unsuccessful
log "doing npm install and npm run build. Make sure .env file is there in source.";
cd $path/versions/$latest_sha && npm install --unsafe-perm && npm run build || (rm -rf $path/versions/$latest_sha && abort npm install and build failed)
# remove previous symlink to current and create the new one.
ln -sfn $path/versions/$latest_sha $path/current
test $? -eq 0 || abort symlink failed
fi
}
# finally deploy.
deploy
#### END ####
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment