Archive for the 'Ruby on Rails' Category

Sunkhak Göteborg

Sunday, March 26th, 2006

Sunkhak GBG is a collection of "sunkhak" in Göteborg, much like Sunkhak.se, which is for Stockholm for now.

Sunkhak GBG is mine and my friend Jonas first common project and also our first Ruby on Rails project. The site is on line at www.sunkhakgbg.info and there is also a WAP interface. Information is being added now and the site could actually be useful in a matter of days or weeks.

Migrating from Apache to LigHTTPD

Wednesday, March 22nd, 2006

After running Apache 2 as the main web server for maybe three or four years I have now made the switch to LigHTTPD, or Lighty. This is due to several reasons, but mainly due to problems with running Ruby on Rails applications behind Apache 2.

There are several ways of running a Rails application. One can use WEBRick, the server usually used during development. It’s all ruby and needs no configuration. Though it’s not that fast, or have heaps of features.
One could run Rails behind Apache with CGI. With this approach you get a good web server, with heaps of features, but CGI isn’t all that good. Actually, the whole Ruby environment will be reloaded in every page view, or rather, every request. This is a real drag on performance and memory use and not preferred.
A Rails application can be run with mod_fastcgi, but the fastcgi module for Apache 2 has not been in active development since late 2003 (afaik) and there are a few known issues that according to the tale have caused some backwards migrations to Apache 1.3.
One can use any other web server capable of CGI or fast CGI, but when it comes to the usual Linux box, it has got Apache running, if any server.

There are also other things to consider. In my case I have a lot of old PHP pages wich I do not want to rewrite. I also had a TurboGears application running behind Apache 2. This application was actually just a CherryPy webserver on a different port wit a proxy from Apache.

So, what I wanted was a way of serving PHP, Ruby on Rails and TurboGears while serving some of these pages over HTTPS. Apache 2 could have done this, of course, but there was issues. Number one, Ubuntu does not ship the usual mod_fastcgi, so I had no nice instructions on how to deploy Rails with my server. The application was ridiculously slow with Apache 2 + CGI so that was not really a choice. I don’t know why, but I have always had bad feelings about running the proxy towards CherryPy. And last, Apache is good, but it’s a beast. It’s huge, and complex, and well, after three or four years I don’t know half of what Apache can do for me. So I started looking at what LigHTTPD could do for me and actually found everything that I need, including a nice blog post about TG and Lighty.

So what did I do? I tried my old friend apt-get install lighttpd but it failed since it was not included in the Hoary Hedgehog. So instead I grabbed the sources and created a .deb package for hoary. This package can be downloaded here if anyone would like to use it. I actually just copied an old debian directory into the new sources, updated the changelog and executed dpkg-buildpackage. This left me with a somewhat strange install, which is what you will get by my package, due to the old debian dir not including some parts of the debian patch. The thing was that the config files was laid out kind of like debian does with Apache so that files can be symbolically linked into the enabled dir and included in the configuration. It took me ages to figure out why the config files symlinked to confs-enabled never was read by the server. However, after fetching the debian source package from unstable i was able to extract one script and also a line needed int the main config file for this setup to work. The scripts can however NOT be put where the patch suggests or the server will never be able to execute them. Here we face another problem. Lighty can execute scripts and use the output as parts of it’s configuration. This is actually how the symlinking works. Debian includes a perl script that reads the directory, sorts the array of files and then outputs what’s in them, which is then included in Lightys configuration. But if Lighty fails to execute the scripts it will never tell you since it seems to completely ignore everything written to stderr. After arguing allot with Lighty i finally put the perl scrits in /usr/bin, added the x flag and tried to run it. The way I found out it worked was to output things that Lighty would not like and then get it to not start.

The script can be found here. Also remember to put include_shell "include-conf-enabled.pl" at the end of the main configuration file. What I have done on my setup is to also create a sites-enabled directory and duplicated the script, just changing which directory to read to keep trac of my v-hosts.

So, with the config parts included at last it was time to begin the migration. I started Lighty on port 3000 and started including a feature at the time, starting with PHP. First of all i created a config file for including the mod_fastcgi, making sure that this is done before PHP (since we will run php with fast_cgi) by calling it 05-fastcgi.conf. The reason it’s not 01 or 00 is that mod_auth must be loaded before mod_fastcgi if you shall be able to use mod_auth for those applications.

01-mod-auth.conf:
server.modules += ( "mod_auth" )
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/path/to/passwords/htpasswd"
auth.backend.plain.groupfile = "/path/to/passwords/groups"
I have not tested if the groups work yet.

05-fastcgi.conf:
server.modules += ( "mod_fastcgi" )

11-php.conf:
fastcgi.server = ( ".php" => (
( "bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 2,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "16",
"PHP_FCGI_MAX_REQUESTS" => "10000" ),
"bin-copy-environment" => ( "PATH", "SHELL", "USER" ),
"broken-scriptfilename" => "enable" )
)
)

On ubuntu I also had to do a apt-get install php4-cgi, or 5 or 3 or whatever. After that I found out I had to edit the php.ini found at /etc/php4/cgi/php.ini and add all the modules that I could find in /etc/php4/apache2/php.ini.
This was added to the cgi php.ini:
extension=mysql.so
extension=mhash.so
extension=imap.so
extension=gd.so
extension=mcrypt.so
extension=domxml.so

Also i had to uncomment cgi.fix_pathinfo=1 to be able to get IMP running. Otherwise it makes a mess of the paths.

To get WordPress to handle permalinks (it usually uses Apaches mod_rewrite + htaccess) i had to add this to the v-host running the blog:
$HTTP["url"] =~ "^/blog/" {
server.error-handler-404 = "/blog/index.php?error=404"
}

Please notice that the blog is on a virtual domain but under the url /blog/
By the way, i do not use mod_simple-vhost, I only use conditional v-hosts, seems just as easy, and the nesting is awesome.

By this time PHP was up and runnig with the same functionality as with the old Apache 2, YAY.

To be able to run Rails on fcgi Ruby needs the fast_cgi module. To be able to build it in Ruby you need to have libfcgi(-dev) installed on your machine. This is a simple apt-get in Ubuntu. fast_cgi will then be installed trough Ruby Gems, or apt-get. I prefer Gems, since my Hedgehog is rather old.

apt-get install libfcgi-dev
gem install fcgi

Now we need a config file to include in Lighty, XX-whatever.conf: $HTTP["host"] == "rails.example.com" {
server.error-handler-404 = "/dispatch.fcgi"
server.errorlog = "/path/to/appliction/log/server.log"
server.document-root = "/path/to/appliction/public/"
fastcgi.server += (
".fcgi" => (
"localhost" => (
"min-procs" => 10,
"max-procs" => 10,
"socket" => "/tmp/rails.fcgi.socket",
"bin-path" => "/path/to/applictian/public/dispatch.fcgi",
"bin-environment" => ( "RAILS_ENV" => "production" ) # if you want to
)
)
)
}

Restart Lighty and you have a shiny Rails application running super fast!!!

Time for Turbo Gears!!
Now, TG will always run with CherryPy, but you can do this in different ways. I choose the hard way, the second on this page. Just do as the guide tells you except do NOT add mod_staticfile. By adding it PHP stopped working. The Python script they are writing could either be rewritten using this recipe or started with start-stop-daemon to get a background process.

This pretty much concludes the story of migrating from Apache 2 to LigHTTPD, I can now run TurboGears (www.sunkhakgbg.info) and PHP on Lighty, and it feels much faster than Apache to.

Ruby, Rails, C and Web Services

Saturday, March 18th, 2006

Much has been going on now…

So far this semester I’ve started programming C, started looked at web services, and also started using Ruby + Ruby On Rails. Now there’s only LaTeX (and maybe C#) left on my semester wishlist :)

So to combine all these technologies I have explored the possibilities of using C inside Ruby by creating a small C program (using SQLite) and wrapping it in Ruby classes. These Ruby classes will then be used in a simple web service handled by Ruby On Rails / Action Web Service and the web service will be demonstrated with a Java/Swing GUI.

So what have I learnt along the way? Well, Ruby is, different. In the beginning the differences just seemed strange but now, after a day or two I get a warm feeling in the stomach when I write something in Ruby. Most of the do I like Ruby? depends on how much I like it compared to other languages, and Python in general. That’s because I’ve done similar stuff in Python.

The one thing I really like about Ruby is that everything is an Object. Well, everything is, and every class inherits from the Object class. I’ve heard this before, when reading about Python, but hey can you do this in python -3.abs.to_s and end up with the string “3″? Not in my shell anyway…

Consider this:

def print_if value
(1..5).each {|num| print num if num.eql? value}
end

It is that kind of thing that seemed weird but gives me the warm feeling today.

Ruby is truly object oriented while Python feels semi object oriented and Java, oh well, we have primitive types, how nice…

Ruby on Rails? Once again, Ruby on Rails vs. TurboGears. The first impression is that Rails seems more stable, more glued together. Just the fact that I had to restart the TurboGears development server whenever I made a typo (syntax error) in the controller, but not with Rails gives me this impression. However, that I manually have to create my database tables in Rails (ActiveRecord) but not in TurboGears gives a different impression. I think the big difference in the end is that I read a book on Rails while just using the docs on http://www.turbogears.org/ for TurboGears. It might also make a difference that TurboGears was at version 0.7 when I used it (now 0.8 / 0.9 alpha).

C? Oh, well… C is, fast? Tedious? Annoying? C is a lot. The fact that I have to write 200 lines for accessing a SQLite data base and actually doing something could make one weep. “But it’s fast to run, not to write.” Yeah, I realise that. Well, I have become sort of used to C by now, and I do tend to feel sick when I hear words like VM or interpreted language but I will not vote for building desktop applications in C :), or web service components for that matter.

So what is my conclusion?
Rails vs. TG? Oh well, if you know Python en enjoy Python, go for TG. If you know Ruby and enjoy Ruby, go for Rails. If you know PHP and enjoy PHP, grow up. Ok, I guess PHP could be nice inside a decent framework, but… then again.
Web services in Rails? Well, it took less than 5 minutes to set one up in the development environment… Seems just as easy as in Visual Studio (latest? version). The only difference would be that I don’t have the Web service button that does it for me. I have to do some horrible typing. Well, I enjoy typing more than using the bloody mouse… From what I have read it would also be rather easy to deploy a Rails web service.
Ruby? Oh well, I think i’m in love. Yes, I know it’s an interpreted language, but hey, whenever will you find the perfect love anyway? The fact that two days after I opened my first Ruby guide (which by the way was the hilarious why’s poignant guide to Ruby) I have created half of “Sunkhak GBG” (see Sunkhak for an idea about what it will be), created a sample webservice and wrapped a C program inside two Ruby classes tells me Ruby is quite easy to learn and understand as well.