deploying static sites using ssh and github

At &yet I maintain and deploy a lot of little sites that are either mostly static or static with some variation of NodeJS, Python or whatever that lives behind a Nginx reverse-proxy. After the Nginx configuration is done and working, the maintenance aspect kicks in and that usually involves a lot of update/deploy iterations.

The method I'm outlining here to do the update/deploy cycle isn't anything new or spectacular - heck some will probably critique it as being too simple, but that's what I was striving for :)

Some assumptions:

  1. Your site is in some repository: git, svn or whatever - it just needs to be ssh reachable
  2. You have configured a ssh key for deploying (see how github does it)
  3. You have an deploy user configured with minimal sudo privs

I will often use a single deploy user on a server if it has multiple sites or a site with multiple repos feeding into a single site - for this you will need to manage your deploy keys because GitHub does not allow you to share a deploykey across repos (it also happens, IMO, to be a good security-minded habit.) Fortunately ssh-agent comes to our rescue!

I add the following to my deploy user's ~/.profile

SSHENV=~/.ssh/agent-${HOSTNAME}
if [ ! -f "${SSHENV}" ]; then
    ssh-agent > ${SSHENV}
fi
. ${SSHENV}

This will inherit any existing ssh-agent environment or start a new one and then make sure the SSH related environment variables all in place. Once that is in place you can manage your deploy keys using ssh-add.

Now we can create a helper script that handle the details - shown here is a really basic one that is verbosely written to illustrate how many details are available to tweak.

#!/bin/bash

SITENAME=static_site
BRANCH=deployable
DEPLOY_KEY=deploy-site-static-key
REPO=git@github.com:foo/${SITENAME}.git

if [ -e /tmp/${SITENAME} ]; then
    rm -rf /tmp/${SITENAME}
fi
mkdir -p /tmp/${SITENAME}

ssh-add ~/.ssh/${DEPLOY_KEY}
git clone ${REPO} /tmp/${SITENAME}

cd /tmp/${SITENAME}
git checkout ${BRANCH}

sudo cp /tmp/${SITENAME}/* /srv/www/${SITENAME}/

Note: I use the "/tmp/${VARNAME}" style out of an old habit of never allowing "rm -rf" to ever have a chance to reference a variable that could expand to "/" - I would rather delete the /tmp tree in that case

Again, the above is not rocket-science or even the latest DevOps craze, but it works and it allows you to encapsulate the deploy knowledge in a way that is also secure and repeatable... and that is always the first step to getting clean automation in place!


Mentions