up
close

using an older version of IE, huh?

We no longer support older version of Internet Explorer on kohv3. For a better experience try upgrading to a newer version of Internet Explor, Firefox or Chrome.

kohv3 will work in older version but for an enhanced experience, we recommend you upgrade.

close client login

Beanstalk Deployment Hook Server

I was recently asked by @beanstalkapp to write a blog / tutorial on my Node JS Hook Server, but I'd like to start by mentioning how awsome of a service beanstalk is for version control. Not only do they host SVN and GIT but their deployments rock, and saved us alot of time having to write our own deployment tool. We use it by creating 2 deployments per project, one to the Development environment and one to the Production environment. The Development environment is almost always set to automatically deploy every commit, saves us the trouble of checking into version control and then FTPing. *AWSOME* not only does that simplify our development cycle it gets us to check-in all of our code on a much more consistant basis than we probably would if we FTP'd everything. We use GIT, we started with SVN but moved to GIT when we started doing more ruby. I guess since bundler was git / github centric we made the switch. I also like the concept of decentralized repos, since i can then check in code offline, and push it when i'm connected again. Enough with the introduction lets get to the meat of developing an easy to use NodeJS Deployment Hook server:

First there are some requirements, you will probably want to have root access to your deployment environments, if you don't have this you may be better off using a PHP solution.

Next install node (if you have this already skip this step):

to install node you have a few options 1) compile it from source or 2) find a package. Depending on your distro this is done in various ways, we use alot of CentOS and Ubuntu so those would be like this:

Ubutu

# apt-get install [node package name]

or

CentOS / Redhat / Amazon Linux

# yum install [node package name]

If you can't find a node package your best bet is to compile from source:

Joyent has good documentation on this. Remember to install your os's build tools, usually there is a package for this as well (try google).

Installing it should look like this:

 

# wget http://nodejs.org/dist/node-v0.4.10.tar.gz

# tar -zxvf node-v0.4.10.tar.gz

# cd node-v0.4.10

# ./configure

make

make install

after that you can check:

whereis node

to ensure you have a successful install.

Now that you have node installed lets make a simple server app:

 

You can basically save that anywhere. Feel free to modify it its just a simple example that implements basic-auth security.

You probably will also want to modify the username and password values on line 11.

The other thing you may want modify is line 17 which contains the path to a shell script that should marked executable:

# chmod +x /path/to/deployment/script

Another thing to note is that this is a very simple example, it anything that properly authenticates to this server will launch this script reguardless of path. Your may want 2 of these or you may want to write something along these lines with actual routing capabilities perhaps based on Express or Connect to handle multiple app deployments as we'll as pre and post deployment hooks. I hope to update this post or create a new one with a more robust script that does that in a couple weeks so if your not sure how to go about it come on back around then.

After your done fiddling around you want to create your deployment script.

Either ftp it over to your server into an accessible location and chmod +x it as described above or fire up nano / pico / vim and create it.

In our case we would:

# nano /usr/share/nodeHooker/hooker.sh

and write the commands for our deployment

For ruby on rails and nginx you may want to restart the server to flush the cache and run bundler to install any new dependencies.

 

cd /path/to/app/folder
bundler install --deployment
service nginx restart

this is most likely not what you will type, it all depends on your environment; for us, we use nginx, phusion passanger and ruby as a stack for most of our projects. If your project is nodejs you may want to do something like

cd /path/to/app

npm install

stop nodejsapp
start nodejsapp

the example above uses upstart to manage a node app, which i will get into in a second since that's how we will be launching our hook server.

Upstart is a initctrl application common in modern Linux OS's you can almost always find this as a package:

# yum install upstart

it may already be installed so don't freak out if it is.

You may have to look up the exact location of where upstart configs are defined but the following works on centOS:

 

# cd /etc/init

Now you want to create a new upstart configuration for the hook server

# nano /etc/nodeHook.conf

In this file you will want to put

#!upstart
description "hooker node.js server"
author      "justinmcnally"

start on runlevel [2345]
stop on runlevel [016]

respawn

script
      	exec /usr/local/bin/node /usr/share/nodeHooker/app.js >> /usr/share/nodeHooker/app.log 2>&1
end script

obviously your path to the hook server app may be different, you should fix it appropriately. Also i am using default runlevels if you modified them you probably need to fix them accordingly on the script. On some distros the concept of runlevel can be simplified to "start on startup" and "stop on shutdown".

The respawn command is awsome because if your node app dies it will restart it. This saves us the trouble of setting up and configuring monit.

now you should be able to start your deployment hook server by typing


start nodeHook

upstart should also automatically start the server on reboot. Although you may need to start upstart on boot which can usually be done with

chkconfig upstart on

If your node server won't run you can debug by checking the log you defined in the upstart script or by actually going into the hook server folder and manually running

node [name_of_file.js]

Sidenote the script included for the node server listens on port 6969 if you can change that at the end where it says .listen(6969, "0.0.0.0"), you could specify a different port or Bind ip there. You should also allow incomming traffic to port 6969 or port specified through your firewall. In EC2 this is in your Security Group, if your using IPTables its best if you google the specefics on allowing traffic to a port. Another option is using ProxyPass in nginx or apache to route to this appserver through port 80 at a specified url, but that's outside of the scope of this post.

Now you need to configure you beanstalk deployment hook to hit this address when a new deployment happens, we only use post-deployment hooks but the script could be adapted processing the json data sent to handle both.

1st login in to beanstalk.

2nd goto the repo for that deploys to this server

3rd select deployments

4th either edit or create a new deployment

5th when you get to the section about adding a deployment hook enter the following into the post-deployment hook box.

 

http://username:[email protected]:6969/

again replace username and password with what you configured the node app to do, and also replace deployment-server-domain.com with the hostname or IP of the server you want to deploy to. If you changed the port number in the server script also replace it in the url.

Save the deployment, if your username or password are wrong it will not let you save, also if the node server isn't running or the host/port are wrong you will also get an error.

Happy deployments.

more posts in:
comments