Thursday, May 11, 2017

Using git push to deploy code to DigitalOcean

There'll be times using a continue integration server or stack is a big pain in the butt. Sometimes we just want to type git push from the terminal and the live app is updated. This is that tutorial although specific to DigitalOcean. I'll bet it will roughly work the same for other cloud services.

Assumptions
  • You have a Digital Ocean server (or droplet) running and configured
  • You have the ssh to said droplet working
So ssh to the droplet and then navigate to /var/www (or anywhere else you want to put your code) and make two directories:

$ mkdir liveapp.com && mkdir appcode.git
$ cd appcode.git

Inside the appcode.git folder we will create a "bare" git repository: git init --bare
A bare git repository doesn't contain our code but rather the internals of the .git folder. The whole point of this is to access the hooks folder within.

The hooks folder have scripts that can be run at certain steps within the git repo's lifecycle. We want a hook script to run after we "receive" a push to this repo. Hence we create a post-receive file inside the hooks folder.

$ vi post-receive

# Type this in

#!/bin/sh
git --work-tree=/var/www/liveapp.com --git-dir=/var/www/appcode.git checkout -f

# save and exit
# make the post-receive hook executable

$ chmod +x post-receive

There! We are done for the server side. We move to the our local machines.

All we actually need is need is to add a remote target in your working git repo. Assuming you added the droplet in your local ssh config then the command should be look like:

$ git remote add droplet ssh://user@ip-of-droplet/var/www/appcode.git

# add a new commit - this will not work even if you existing commits
# you must have a new commit
$ git add .
$ git commit -m "new commit"

# push to repo - could be github or bitbucket
$ git push

# push to droplet
$ git push droplet master

If all goes to plan, then our code will show in our new "git work tree" which is the liveapp.com folder inside our droplet.

A couple more thoughts:
  1. It's fairly easy to setup a sort of staging or testing folder/area with this.
  2. The post-receive script can do more things like a "restart app" or send mail to admin for notification. It's just a bash script.