Skip to content

Instantly share code, notes, and snippets.

@adammcarth
Created February 20, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adammcarth/b50b5376ab95f469aaaf to your computer and use it in GitHub Desktop.
Save adammcarth/b50b5376ab95f469aaaf to your computer and use it in GitHub Desktop.
Deploys code from a GitHub repository to an ec2 instance (or any linux-based VPS).
#!/usr/bin/env bash
source ~/.rvm/scripts/rvm
rvm use
#`deploy.sh` v0.0.1 by Adam McArthur.
# Deploys code from a GitHub repository to an ec2 instance.
# It is reccommended that the current user can use "sudo" without a password [you might need to use sudo from inside this script],
# See: http://askubuntu.com/questions/235084/how-do-i-remove-ubuntus-password-requirement#answer-235088
##### SETTINGS [Change Me] #####
# Used only for status notification messages
app_name="My App"
# Location on the server where your apps are stored
apps_dir="/var/www"
# GitHub repository info
github_username=""
git_repo=""
# The path your application will be cloned to
app_path="$apps_dir/$git_repo"
# Where are your log files?
log_files="$app_path/server/log"
# Where on the server should your log files be archived to after each deployment?
archived_log_files="$apps_dir/archived_log_files"
# App install commands must succeed before the current running application is shut down...
app_install_commands=""
# How is your application started? (Run from inside the actual application directory)
app_startup_commands=""
# Commands to be run when application startup is successful
post_startup_commands=""
post_startup_commands_2=""
# How is the application shut down? (Run from inside the actual applciation directory) [if statement used in case first time deploying]
app_terminate_commands=""
##### SCRIPT [Leave Me] ######
Bold='\033[1m'
Red='\033[1;31m'
Yel='\033[1;33m'
Gre='\033[1;32m'
Clear='\033[0m'
if [ -z $GIT_BRANCH ]; then git_branch="master"; else git_branch=$GIT_BRANCH; fi
app_old=$app_path"_old"
app_pending=$app_path"_pending"
app_failed=$app_path"_failed"
echo
echo
echo
echo -e "${Bold}==== DEPLOYMENT STARTING ====${Clear}"
echo
# Stop script if an error occurs
set -e
# Create apps dir if it for some reason gets removed...
if [ ! -d $apps_dir ]; then
echo -e "Warning: '${Red}$apps_dir${Clear}' doesn't currently exist. Attempting to create it..."
sudo mkdir $apps_dir
sudo chown -R $(whoami):$(whoami) $apps_dir
echo -e "${Gre}Directory created.${Clear} Proceeding with deployment..."
fi
# Make sure apps dir is writable
if [ ! -w $apps_dir ]; then
echo -e "Warning: '$apps_dir' is not currently writable. Attempting to repair permissions..."
sudo chown -R $(whoami):$(whoami) $apps_dir
echo -e "${Gre}Permissions have been successfully repaired for '$apps_dir'.${Clear}"
fi
echo
echo -e "${Bold}01. Clearing files from last deployment in '$apps_dir' directory...${Clear}"
cd $apps_dir
rm -r -f $app_pending
rm -r -f $app_error
rm -r -f $app_failed
echo
echo -e "${Bold}02. Downloading latest version from $git_repo:$git_branch...${Clear}"
git clone https://github.com/$github_username/$git_repo.git $app_pending
cd $app_pending
git checkout $git_branch -f
echo
echo -e "${Bold}03. Repairing permissions for '$app_pending'...${Clear}"
cd $apps_dir
chown -R $(whoami):$(whoami) $app_pending
echo
echo -e "${Bold}04. Installing dependancies for new deployment...${Clear}"
cd $app_pending
$app_install_commands
echo
echo -e "${Bold}05. Terminating current application...${Clear}"
if [ -d $app_path ]; then
cd $app_path
$app_terminate_commands
else
echo -e "Notice: It looks like this is your first time deploying $app_name to '$apps_dir'. Skipping this step."
fi
echo
echo -e "${Bold}06. Archiving old log files...${Clear}"
if [ -d $log_files ]; then
mkdir -p $archived_log_files/$git_repo/$(date +'%Y')/$(date +'%m')/$(date +'%d')/$(date +'%H'):$(date +'%M')/$(date +'%N')
scp -r $log_files $_
else
echo -e "Notice: Couldn't find the specified log files directory at '$log_files'. Skipping this step."
fi
echo
echo -e "${Bold}07. Replacing contents of '$app_path' with '$app_pending'...${Clear}"
if [ -d $app_path ]; then mv $app_path $app_old; fi
mv $app_pending $app_path
echo
echo -e "${Bold}---------------------------------"
echo
#We'll handle the errors from this point.
set +e
echo
echo -e "${Bold}08. Starting new application...${Clear}"
cd $app_path
if $app_startup_commands; then
rm -r -f $app_old
$post_startup_commands
$post_startup_commands_2
echo -e "${Gre}[APPLICATION NOW RUNNING] $app_name has been deployed successfully :)${Clear}"
echo
exit 0
else
echo -e " ${Bold}${Red}[FAIL!] Couldn't start the application (${Clear}#1${Red}): ${Yel}Retrying...${Clear}"
echo
if $app_startup_commands; then
rm -r -f $app_old
$post_startup_commands
$post_startup_commands_2
echo -e "${Gre}[APPLICATION NOW RUNNING] $app_name has been deployed successfully :)${Clear}"
echo
exit 0
else
echo -e " ${Red}[FAIL] Couldn't start the application (${Clear}#2${Red}): ${Yel}Reverting to previous build...${Clear}"
echo
mv $app_path $app_failed
mv $app_old $app_path
cd $app_path
if $app_startup_commands; then
$post_startup_commands
$post_startup_commands_2
echo
echo -e "${Yel}...Reverted to previous build successfully. The latest build could not be started, and is likely due to a runtime error on startup.${Clear}"
exit 3
else
echo -e "${Red}[Fatal Error] Neither version of the application could be started. This is a most likely an issue on the server side, and requires immediate attention. No application is currently running.${Clear}"
echo
echo "..."
echo
echo -e "Current structure in '$apps_dir':"
ls $apps_dir
echo
exit 3
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment