Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

`sc-deploy` overhauled. Now keeps 5 deployments on the server by defa…

…ult rather than keeping them forever. You can adjust this number via the `KEEP` variable in `deployment/settings`. Also, `sc-deploy` does a better job of recognizing problems at the end of the deployment process and will flip the symbolic link back to the previous deployment and attempt to restart that version of the code if deployment fails.
  • Loading branch information...
commit 05fee2b546bad840b1c5e1be34a0a526db7d5802 1 parent 8fa9616
Tom Boutell boutell authored
Showing with 65 additions and 15 deletions.
  1. +6 −0 README.md
  2. +57 −13 bin/sc-deploy
  3. +2 −2 example/deployment/start
6 README.md
View
@@ -34,6 +34,8 @@ Like other deployment tools, sc-deploy deploys to a new folder on the target ser
`sc-deploy` creates a symbolic link from `/opt/stagecoach/apps/example/current` to the latest deployment folder if everything happens successfully (assuming that your project is called `myproject` and you base your paths on those in `example`). If you're deploying traditional web languages like PHP, you'll want to make sure your web document root is configured accordingly.
+**By default, 5 old deployments are kept on the server.** This is useful if you need to roll back. You can change this number by setting `KEEP` in your `deployment/settings` file.
+
`sc-deploy` relies on bash scripts in a subdirectory of your project called `deployment` to carry out the work of starting (`start`), installing dependencies for (`dependencies`), stopping (`stop`) and migrating (`migrate`) your project. If any of these scripts exit with a nonzero status, the deployment process stops and the previous version of the site stays live. Currently any failed deployment folders are left on the server for your debugging convenience.
Settings that apply to all deployment targets for this project, such as the project's name and (usually) the deployment directory, reside in `deployment/settings`. You'll want to edit the `PROJECT` setting, and possibly the `DIR` setting as well. The project name should be a reasonable Unix shortname; it's the folder name you'll be deploying to. If you use `sc-proxy` it is also the subdomain you'll use to access the staging site.
@@ -128,6 +130,10 @@ You don't have to use Ubuntu. But if you do, you might find this shell script ha
This shell script is provided in the `sc-proxy` folder. It does what it says: it installs Node and MongoDB correctly on Ubuntu, using the recommended repositories for the latest stable releases, not the older stuff in Ubuntu's official repositories. It also configures MongoDB to run safely, accepting connections only on localhost. You can change that if you like, just please consider the security implications. MongoDB's default configuration has no security of any kind, so our changes make sense.
+## Changelog
+
+06/18/2013: `sc-deploy` overhauled. Now keeps 5 deployments on the server by default rather than keeping them forever. You can adjust this number via the `KEEP` variable in `deployment/settings`. Also, `sc-deploy` does a better job of recognizing problems at the end of the deployment process and will flip the symbolic link back to the previous deployment and attempt to restart that version of the code if deployment fails.
+
## Contact
[tom@punkave.com](tom@punkave.com) mostly maintains this. You can also [open issues on github](http://github.com/punkave/stagecoach). We welcome pull requests.
70 bin/sc-deploy
View
@@ -31,15 +31,24 @@ VERSION=`date "+%Y-%m-%d-%H-%M-%S"`
# start is run after the symlink is changed so the current directory looks
# more reasonable to other scripts.
-DEPLOYTO="$DIR/deployments/$VERSION"
+DEPLOYMENTS="$DIR/deployments"
+DEPLOYTO="$DEPLOYMENTS/$VERSION"
CURRENT="$DIR/current"
+# Keep 5 deployments by default
+if [ -z "$KEEP" ]; then
+ KEEP=5
+fi
+
+# For use with tail -n
+KEPT=$[$KEEP+1]
+
# For now we just don't check whether 'stop' worked, because it fails on the first
# deploy (chicken and egg problem, stop isn't there yet). TODO: fix this with
# an 'if folder exists' test on the server; make the remote script a multiline,
# maintainable thing
-ssh -p $SSH_PORT $USER@$SERVER "mkdir -p $DIR/deployments" &&
+ssh -p $SSH_PORT $USER@$SERVER "mkdir -p $DIR/deployments" &&Mig
rsync -e "ssh -p $SSH_PORT -l$USER" -C -a --delete $EXCLUDE . $USER@$SERVER:$DEPLOYTO &&
ssh -p $SSH_PORT $USER@$SERVER <<EOM
$ADJUST_PATH
@@ -49,19 +58,54 @@ ssh -p $SSH_PORT $USER@$SERVER <<EOM
if [ -f $DEPLOYTO/deployment/dependencies ]; then
cd $DEPLOYTO
bash deployment/dependencies
- if [ \$? -ne 0 ]; then
- echo "Deployment failed during dependencies script!"
- exit 1
+ fi
+ if [ \$? -eq 0 ]; then
+ # Stop old deployment if any
+ if [ -e $CURRENT ]; then
+ # Don't give up yet if we can't stop the old deployment - it might just be
+ # broken and the main reason we're deploying a new one
+ FORMER=\`readlink $CURRENT\`
+ if [ \$? -eq 0 ]; then
+ cd $CURRENT &&
+ echo "Stopping previous deployment" &&
+ bash deployment/stop
+ else
+ echo "Previous deployment is missing"
+ fi
+ fi
+ # Run migrations and start new deployment after flipping symlink
+ cd $DEPLOYTO &&
+ bash deployment/migrate &&
+ rm -rf $CURRENT &&
+ ln -s $DEPLOYTO $CURRENT &&
+ cd $CURRENT &&
+ bash deployment/start
+ fi
+ # If deployment failed, relink and restart the previous deployment
+ if [ \$? -ne 0 ]; then
+ echo "ERROR on deployment"
+ if [ -n "\$FORMER" ]; then
+ echo "Relinking previous deployment"
+ rm -f $CURRENT
+ ln -s \$FORMER $CURRENT &&
+ echo "Restarting previous deployment" &&
+ cd $CURRENT && bash deployment/start
+ else
+ echo "There is no prior deployment to restart."
fi
+ echo "Removing failed deployment"
+ rm -rf $DEPLOYTO
+ # Maintain a nonzero status so we know it's an overall failure
+ false
+ else
+ echo "Launch successful."
+ echo "Removing old deployments as appropriate..."
+ # ls sorts alphabetically by default, our deployments are named to sort that way
+ # Thanks to @xavismeh for the tail -n approach
+ echo "Keeping $KEEP deployments"
+ find "$DEPLOYMENTS" -mindepth 1 -maxdepth 1 | sort -r | tail -n +$KEPT | xargs rm -rf
+ echo "Done."
fi
- cd $CURRENT
- bash deployment/stop
- cd $DEPLOYTO &&
- bash deployment/migrate &&
- rm -rf $CURRENT &&
- ln -s $DEPLOYTO $CURRENT &&
- cd $CURRENT &&
- bash deployment/start
EOM
if [ $? -ne 0 ]; then
4 example/deployment/start
View
@@ -36,9 +36,9 @@ else
fi
# Run the app via 'forever' so that it restarts automatically if it fails
-# Use `pwd` to make sure we have a full path, forever is otherwise easily confused
+# Use `pwd` to make sure we have a full path, forever is otherwise easily confused
# and will stop every server with the same filename
-forever -o data/console.log -e data/error.log start `pwd`/server.js && echo "Site started"
+forever --minUptime 1000 --spinSleepTime 5000 -o data/console.log -e data/error.log start `pwd`/server.js && echo "Site started"
# Run the app without 'forever'. Record the process id so 'stop' can kill it later.
# We recommend installing 'forever' instead for node apps. For non-node apps this code
Please sign in to comment.
Something went wrong with that request. Please try again.