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:
- Your site is in some repository: git, svn or whatever - it just needs to be ssh reachable
- You have configured a ssh key for deploying (see how github does it)
- 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!