Get to know a gem: Ghost
16 comments Latest by Endep Fri, 19 Feb 2010 12:55:04 GMT
In my last post, Subdomain accounts with Ruby on Rails explaind, I mentioned that you’d need to modify your /etc/hosts file to use custom subdomains for development/testing. Apparently, there is a much better way to handle this that I was introduced to by Nathan de Vries. Nathan suggests using a gem that I hadn’t heard of before that bares the name of Ghost (view project on github).
Ghost describes itself as…
“A gem that allows you to create, list, and modify local hostnames in 10.5 with ease⦔—
If you’ve ever had to modify your /etc/hosts file for anything local, I highly encourage you to check out this shiny gem.
Installing Ghost
Like most gems, you can just install Ghost with the following command.
~ : sudo gem install ghost
Password:
Successfully installed ghost-0.1.2-universal-darwin-9
1 gem installed
Installing ri documentation for ghost-0.1.2-universal-darwin-9...
Installing RDoc documentation for ghost-0.1.2-universal-darwin-9...
Okay, now that Ghost is installed, let’s see what we can do with it.
Using Ghost for local domains/subdomains
Ghost is fairly straight forward. It’s essentially a friendly wrapper for dscl, which is the Directory Service command line utility for Mac OS X. I’ve never played with that directly, but it seems that with Ghost… I shouldn’t need to. :-)
With Ghost, you can add, modify, and delete entries in the Directory Service by issuing any of the following commands. Let’s start out by running ghost to see what we have here.
~ : ghost
USAGE: ghost add <hostname> [<ip=127.0.1.1>]
ghost modify <hostname> <ip>
ghost delete <hostname>
ghost list
ghost empty
Okay, let’s see if there is anything already listed.
~ : ghost list
Listing 0 host(s):
Nope. Let’s test this out. First, we’ll try to ping a domain name that we hope doesn’t exist.
~ : ping bigbrown.cow
ping: cannot resolve bigbrown.cow: Unknown host
Alright, now we’ll add bigbrown.cow with ghost.
~ : ghost add bigbrown.cow
Password:
[Adding] bigbrown.cow -> 127.0.0.1
As you can see, it required root credentials to do this as it’s system-wide. Let’s now see if we can talk to bigbrown.cow.
~ : ping bigbrown.cow
PING bigbrown.cow (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.047 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.035 ms
^C
--- bigbrown.cow ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.035/0.041/0.047/0.006 ms
Excellent! If we run ghost list again, we should see this record.
~ : ghost list
Listing 1 host(s):
bigbrown.cow -> 127.0.0.1
We can modify the record to a non-localhost IP as well with ghost modify.
~ : ghost modify bigbrown.cow 192.168.10.104
[Modifying] bigbrown.cow -> 192.168.10.104
~ : ghost list
Listing 1 host(s):
bigbrown.cow -> 192.168.10.104
I’ll let you play with it yourself as there isn’t much to it. This is a great little addition to my development environment. Thanks to Nathan for pointing it out and to Bodaniel Jeanes for creating this useful gem.
Enjoying the content? Be sure to subscribe to my RSS feed.






Nice post but after reading it I’m not sure it saves much time/trouble over just firing ‘mate /etc/hosts’.
s/bares/bears/
Small nifty tool, but I really see no practical use. Mate /etc/hosts indeed, anyone?
Cool, good gem to add to my toolbox. Is there a way to make ghost (or dscl for that matter) set wildcards for subdomains?
@Ryan
Unfortunately no. dscl will let you add them but it doesn’t work. That’d truly make it useful.
@Apostlion, @Swami
The gem is actually a library that you can use in other scripts/apps. The command line app is just one end point for using it. Other benefits of the command over ‘mate /etc/hosts’ (at least for me) is that it also clears the dns cache for you and in my experience works immediately, whereas using the hosts file, it seems that some apps cache the dns entries (Firefox, I am looking at you). If hosts file works for you then by all means this might not bring a whole lot to your workflow, but I personally like being able to list and manipulate the entries from a command.
Also my project hostjour (which I should probably finish) was designed to take ghost’d entries and advertise them on your local network so that anyone who also had ghost would have them immediately added to their local dscl (pointing to your machine). Ideal for situations like RailsCamp when your apps are running using Passenger.
@Robby thanks for the write up!
@Apostlion You mean
mate /etc/hosts
sudo dscacheutil -flushcache
and then possibly restart your browser if you out of habit tried out the domain there first and then it got cached in the browser dns cache :)
When editing /etc/hosts is just too much effort:
echo “127.0.0.1 mynewhost” >> /etc/hosts
Also, more love for Linux/BSD/Anything-Unixy. Now don’t get me wrong, that ghost gem might do great stuff, but for adding an entry to the hosts file for dev work it does seem a little overblown :)
Yes, in OSX, you need to run the following after you modify
/etc/hosts.sudo dscacheutil -flushcacheghost does that for you. ;-)
I wrote a similar gem this week called ‘hoster’ that modifies /etc/hosts directly so it can be used in other environments beside Mac OS 10.5.
The source is on GitHub and can be installed by running:
sudo gem install sant0sk1-hoster --source http://gems.github.com/I can certainly see this being useful when testing subdomain specific functionality … and instrumenting /etc/hosts in your tests is just not going to be as reliable (or safe).
Thanks for the writeup.
@Johannes
I couldn’t agree more. The idea was to eventually have adapters for all different systems (dscl for leopard, the extremely hidden hosts file in windows, and /etc/hosts everywhere else) so that all developers could manage hosts with a common command (and library) without having to think. /shrug, maybe i’ll add it one day
you mean ‘sudo /etc/hosts’, and that’s the difference for me.
Tell a lie; that’s just because I ran the ghost commands in a Terminal that had just run ‘sudo gem install ghost’. Doh.
This post was fun right up until I got to the part about installing Ruby Cocoa for the pref pane. Trying to installing Ruby Cocoa from macports along side my current 1.9 macports install didn’t work out too well for me.
I used dnsmasq with a .dev domain and never have to update /etc/hosts.
http://blog.steamshift.com/geek/leopard-lookupd-and-local-web-development-sites
But with Snow Leopards broken split DNS i’ve had to go back to /etc/hosts looking forward to using this to save one step in the new application process.
Great. I try to use it right now!