If you see it, you’ll #### bricks. The things programmers make users deal with…
It can be annoying to maintain a git repository on your web server and use commit hooks to install new code. Here’s a way to still use git, but instead use rsync to push those updates to the server.
It’s good to be back!! Despite how much fun it was developing my own blogging/publishing framework with Node.js, I never actually got around to publishing much
Although I did learn a thing or two about the holy trinity… node.js – Amazon EC2 – git.
I’d like to say I’m back in business, but you know how it goes: full-time job, multiple side-projects, team call-ins, mouths to feed, etc… at least it’s now easier to publish something when the mood strikes!
In the previous post where we managed our node.js server with supervisor, we used a classic init script to have supervisor start on reboot. In this receipe, we’ll instead use upstart, a replacement for init bundled with Ubuntu distributions.
Previously, we created this file in our home directory, so you might still have that first copy in case you want to go back doing it the old-fashioned way
$ sudo /etc/init.d/supervisord stop
$ sudo rm /etc/init.d/supervisord
Create a new file /etc/init/supervisor.conf. Its content should look like this:
description "supervisor"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /usr/local/bin/supervisord --nodaemon --configuration /etc/supervisord.conf
Note that we’re using the same supervisord configuration file we used before. No changes there…
This upstart script is modified from one found at lincoln loop. The problem with using ‘supervisord.conf’ as the upstart script filename is that the command supervisorctl picks that up and attempt to use it as a supervisor configuration file, which it is NOT. By changing the upstart script and service description to simply supervisor sans ‘d’, we can use supervisorctl normally.
We can now start and stop supervisord with the following commands
$ sudo stop supervisor
$ sudo start supervisor
To check the status of supervisor
$ initctl list
$ initctl status supervisor
I’m involved with a project where our ruby/rails developer dropped out, so I decided to take on the job using node.js (rather than learn rails). We initially were using services from dotCloud, but it was too flakey from day to day and our demo was coming up. For hosting, Amazon’s EC2 was the obvious candidate, but I’d have to setup and provision the entire server from scratch. This is that story
First things first, login to your AWS console and launch a new Ubuntu Linux image for your new EC2 server. Select the Community AMIs tab and search for this one:
099720109477/ebs/ubuntu-images/ubuntu-maverick-10.10-i386-server-20101225
I choose Ubuntu over other Linux distributions because more of what I needed was already available via the standard package manager (redis, couchdb, etc…). At this point, I usually assign an elastic IP address to my new instances before proceeding with ssh.
Once your new instance is up and running, login and update the system. The upgrade might take some time.
$ sudo apt-get update
$ sudo apt-get -y upgrade
This will make it easy to manage services
$ sudo apt-get install rcconf
$ sudo apt-get install build-essential
$ sudo apt-get install libssl-dev
$ sudo apt-get install git-core
libssl-dev is needed to use the crypt node.js package
You can view the [node.js installation instructions](https://github.com/joyent/node/wiki/Installation “Node.js installation”) or just follow what I did.
$ wget http://nodejs.org/dist/node-latest.tar.gz
$ tar xzf node-latest.tar.gz
$ cd node-v0.4.7
$ ./configure --prefix=/usr
$ make
$ sudo make install
I used –prefix=/usr to install node on the existing PATH. make install can take quite a while… go brew some espresso.
Get the latest npm from github and install.
$ cd ~
$ git clone http://github.com/isaacs/npm.git
$ cd npm
$ sudo make install
$ cd ~
$ npm install connect redis connect-redis jade express express-resource futures emailjs
$ sudo apt-get install nginx
Edit the nginx default configuration file replacing the root (/) location section
$ sudo vi /etc/nginx/sites-enabled/default
Use a proxy passengry entry. This will forward your requests to your node server
location / {
proxy_pass http://127.0.0.1:8124/;
}
Restart ngnix
$ sudo /etc/init.d/nginx restart
$ mkdir ~/www
$ cd ~/www
$ cat > server.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
Start the server
$ node server.js
Test in a browser by navigating to http://your.static.ip/
Shutdown your new server before continuing…
Now we’ll get to the good part where we can leverage git to deploy new server code
Create a bare repository outside the www folder
$ mkdir ~/repo
$ cd ~/repo
$ git init --bare
Create a post-recieve hook that will copy over new code after it’s been pushed to the repository
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/home/ubuntu/www
export GIT_WORK_TREE
git checkout -f
$ chmod +x hooks/post-receive
On your local development machine, setup a repository for your new server
$ mkdir helloworld
$ cd helloworld
$ git init
$ git remote add ec2 ssh://ubuntu@your.static.ip/home/ubuntu/repo
$ cat > server.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
$ git add server.js
$ git commit -m 'first'
$ git push ec2 +master:refs/heads/master
you only need to specify +master:refs/heads/mast the first time
Test in a browser by navigating to http://your.static.ip/
dotCloud uses supervisor to keep node servers up after reboot and crashing. We’ll do the same. So, back on your EC2 instance:
$ sudo apt-get install python-setuptools
$ sudo easy_install supervisor
$ curl https://raw.github.com/gist/176149/88d0d68c4af22a7474ad1d011659ea2d27e35b8d/supervisord.sh > supervisord
$ chmod +x supervisord
$ sudo mv supervisord /etc/init.d/supervisord
check the supervisord service in the services list using rcconf
$ sudo rcconf
$ sudo echo_supervisord_conf > supervisord.conf
$ sudo mv supervisord.conf /etc/supervisord.conf
$ sudo vi /etc/supervisord.conf
chmod=0777 ; sockef file mode (default 0700)
This is under the [supervisord] section
user=ubuntu
Note that we can set the NODE_ENV variable here.
[program:node]
command=node server.js
directory=/home/ubuntu/www
environment=NODE_ENV=production
$ supervisorctl reload
You can also restart the service
$ /etc/init.d/supervisord restart
In the post-recieve git hook we previously created, append a final command that restarts supervisord
$ vi ~/repo/hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/home/ubuntu/www
export GIT_WORK_TREE
git checkout -f
sudo supervisorctl restart node
Now you can work on a local development machine, push your changes to the server using git, sit back and relax while the post-recieve hook tells supervisor to restart your node server. Refresh the browser and throw the confetti!
Today I churned out a WordPress plugin that imports Delicious export files converting bookmarks to posts. See my previous post on how to export your Delicious bookmarks to an XML file. As you may know, Yahoo! is “sunsetting” Delicious, so I took up the challenge to make WordPress do my bookmarking bidding…
I use custom post types and post metadata to make WordPress behave like Delicious. It’s fairly simple. I was also able to use the standard WP tags taxonomy.
Tomorrow, I hope to create a repository at BitBucket.org and make the source available to anyone… =)
Watch this space for internet filled goodness!
Here’s another post showing how I use the Domainer Plugin for WordPress. These are some of top names right now at Snapnames with the most bidders.
Check out the Domainer Plugin over at API Domainers today!
[domains snapnames]
bargainphone.com
sno.net
pmcn.com
sets.net
gradingcontractor.com
homebusinessopportunities.com
phonelife.com
homebusinessopportunity.com
milfweb.com
wineworkshop.com
courtsonline.org
globalpositioningsystem.com
mumbaihomes.com
anzcies.org
manilastandardonline.com
nylonrope.com
deev.com
freebargins.com
horseracewager.com
clubfest.com
brainstimulator.com
onlinecasinopromos.com
spidermancollector.com
windpad.com
austriatrade.com
[/domains]
Some names I quickly copied from my lists today. I’m using the “Domainer Plugin for WordPress” that I’ve developed. You can pick it up at API Domainers.
The plugin lets you easily create domain lists that include your affiliate links for Snapnames, GoDaddy, Sedo and Afternic. Pretty Handy!
[domains snapnames]
mailboxplus.com
livefish.org
australiapackages.com
automachine.com
healthybeer.com
opentemplates.net
portabletranslators.net
[/domains]
[domains snapnames]
historyschool.com
openrent.com
easyanimals.com
californiatimes.org
easybedding.com
clickcanada.com
mazes.us
elitetheme.com
testwizard.net
instantfences.com
accessclipart.com
[/domains]
I thought I’d try this out first on this blog and get some initial reactions. It’s part landing-page big in-your-face button, part friends profile gallery… anyway, it’s a call to action!
If you’re a domainer who’s looking for some extra WordPress Plugin Swag, then JOIN the API Domainers on Facebook today!
[box]
[right]
[button href="%joinurl%"]Join[/button]
[p clear]
Join the
API Domainers
on Facebook!
[/p]
[/right]
[fb_group_gallery count="15" columns="5"][/box]