Heroku Style Deployments With git-deploy
Ever since I started using git-deploy I spend more time on chilling - William Henry Harrison
I have been working more and more on *nix systems lately and a lot less with Windows. Thus, I have deployed a fair amount of apps to Heroku as of late. One thing I enjoy about deploying to Heroku is how using git you can push your code to the server. To give you an example, after installing the Heroku Toolbelt, quite simply all you need to do to deploy is from within your repo:
$ heroku create $ git push heroku master
Heroku will go ahead and build your application while you sit back and relax. I think this is awesome, but, was wondering how I can do this on a local server? Now before I introduce you to git-deploy let me tell you that you can do the same using git hooks but I think git-deploy is a nice abstraction.
I am going to be using Ubuntu 12.04.4 LTS server that I have running on VirtualBox. This is a clean install and I am going to only show how we get this server ready to be deployed to.
Firstly you will need to install git on the remote server, since git-deploy uses Ruby to execute deploy ments scripts you will need to install Ruby too. I am on an Ubuntu box so I will use the following command:
root@super-server:/home# apt-get install git
It is good practice to have your application run by a service account; we will, therefore, create a new user on our server to run our example application.
Now one thing that isn’t so great is the fact that we need to add our new user to the sudo group but this is key for this to work. Log into the server as root or sudo the below commands:
root@super-server:/home# adduser donkey
For this to work OpenSSH or equivalent should be installed on your server. The remote server is going to need a copy of the ssh keys for each user who will be push changes to it via git. Copy your ssh key into the authorized_keys file in the .ssh directory of the service user.
On your local machine copy your ssh key using:
$ pbcopy < ~/.ssh/id_rsa.pub
Back on the remote server use vi to edit the authorized_keys file:
root@super-server:/home# cd donkey root@super-server:/home/donkey# mkdir .ssh && chmod 700 .ssh root@super-server:/home/donkey# touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys root@super-server:/home/donkey# vi .ssh/authorized_keys
This will open up vi paste your ssh key and make sure to save your changes. To make sure everything is in order we restart the ssh server:
root@super-server:/home/donkey/.ssh# stop ssh ; start ssh
Now jump back to your local machine. For this to all work you are going to need Ruby and RubyGems installed on your local machine. Keep in mind this is only applicable to the user who is going to set up the git deploy, everyone else is just going to add a remote to the server where the deployed application will reside.
With Ruby and RubyGems installed you can install git-deploy:
$ gem install git-deploy
Now navigate to your repository and we will setup using git-deploy. For my application, I have the following structure:
kong/ └── app └── index.html
##Show me the money
My application is already under source control, so I don’t need to run git init on it; rather I can just add a remote that points to the production server.
$ git remote add production 'firstname.lastname@example.org:/home/donkey/kong'
I can now run the following commands that will setup the necessary hooks on the remote server
$ git deploy setup -r production [production] $ mkdir -p /home/donkey/kong [production] $ cd /home/donkey/kong && \ git init && \ git config receive.denyCurrentBranch ignore Initialized empty Git repository in /home/donkey/kong/.git/ FILE: [local] hooks/post-receive.sh -> [production] /home/donkey/kong/.git/hooks/post-receive [production] $ chmod +x /home/donkey/kong/.git/hooks/post-receive
At this stage, we need to create the folder that will contain the script files that will run after we have pushed our changes. So still on our local machine run the following:
$ git deploy init create deploy/after_push chmod deploy/after_push create deploy/restart chmod deploy/restart create deploy/before_restart chmod deploy/before_restart
It’s pretty clear what the purpose of these scripts are but here is a short description.
This file is will be run after you’ve pushed your code to the remote server. It gathers some information about your changes, sets up the environment and kicks off the before_restart and restart scripts.
Use this script to run migrations or make any changes necessary before the application starts up.
This is where you will add the commands to start your application.
##Here We Go
You will edit or add additional scripts that will be called from these scripts to ensure all setup is correct for your application. At this point our folder structure will look as follows:
kong/ ├── app │ └── index.html └── deploy ├── after_push ├── before_restart └── restart
The next step is to commit our changes to source control:
$ git add --all $ git commit -m "Repo setup to be used with git-deploy"
Now comes the awesomeness, it’s time to push our changes to the server.
$ git push -u production master Counting objects: 8, done. Delta compression using up to 8 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (8/8), 1.33 KiB | 0 bytes/s, done. Total 8 (delta 0), reused 0 (delta 0) remote: HEAD is now at 03970d6 Repo setup to be used with git-deploy To email@example.com:/home/donkey/kong * [new branch] master -> master Branch master set up to track remote branch master from production.
I have a web server running on the remote server that will display the index.html page:
To prove that everything is in working order I will change the text of that page from:
Then I make sure to commit my code to source control and push to the server:
$ git add --all $ git commit -m "Updated h1 text" [master 224ca0a] Updated h1 text 1 file changed, 1 insertion(+), 1 deletion(-) $ git push -u production master