New Staging Environment in LiteSpeed

Posted by Sam

In version 3.3.4 of LiteSpeed they have finally added a staging environment for Ruby on Rails. This is a big deal for me because every site I create gets a staging environment. In a previous post I blogged about setting up custom environments for Rails in LiteSpeed, but with the new staging environment the code changes in that blog are no longer required. I'm very happy about this and it's nice to see my only real complaint with LiteSpeed fixed. Although now that they've added the staging option maybe they can expose a web service to add new web sites. It would be great for scripting the setup of new sites!

Tags: litespeed rubyonrails

Easy Ruby on Rails Deployments

Posted by Sam

A couple of days ago a large web hosting company named DreamHost posted a blog about how Ruby on Rails could be improved. Some of what they are wrestling with I also wrestled with when we first started deploying Rails applications. But honestly I figured out how to overcome these problems several years ago so I'm wondering what their problem is. Just to put my money where my mouth is I thought I would touch on their points one by one.

Ruby on Rails needs to be a helluva lot faster. With a proper accelerator it’s nicely usable but without one it’s painful. Ruby itself is a big part of the problem so this one may come down to just simplifying the management of the accelerator technologies, unfortunately. Mongrel seems like a big step in the right direction, even though it’s not Rails-specific. I hope the Rails core developers will be cooperating a lot more closely with Mongrel developers in the future. Ok, where to begin on this. First of all let me say for the record that I don't understand why everybody insists on saying Rails is soooo slow. Judging by all the Rails is slow posts all over the net you would think it takes days to load a page, yet these folks handled it just fine. Any technology can fold under traffic and just about any technology if used correctly can scale. Is Ruby the fastest language? No, definitely not. Neither is PHP. If you really need speed you need to go with Java or C and you need to code it correctly. A fast language alone is no guarantee of performance. And because PHP has to startup every time a request comes in it can easily be much slower than Rails.

As for Mongrel being a big step in the right direction I couldn't disagree more strongly. Mongrel is a nightmare for hosting more than one or two sites. Having to setup clusters that don't grow and shrink based on the load is ridiculous. Especially for a shared hosting environment. I can't believe people have latched on to this so much and if Zed is so brilliant why can't he think of a MUCH better way to handle this. LiteSpeed handles this a million times better. Basically just tell LiteSpeed the maximum number of Rails instances and it handles bringing them up and down to handle the load. Oh yeah and LiteSpeed is much faster than Apache so all the way around it's a better setup.

Ruby on Rails needs to more or less work in ANY environment. You can’t just expect your users to set up their servers any which way. There are millions of established systems that cannot simply integrate any bleeding edge technology you think is better this week. If you continue to keep this attitude you are surely shooting yourselves in both feet. I'm guessing by any environment what they are really upset about is that it doesn't work in their environment. Guess what? To support a new technology you often have to make changes. When Java came on the scene you had to add additional application servers, which is far more of a pain than what Rails asks of you. And it does work in pretty much environment. Your real complaint is that it doesn't work in your broken environment. This is really your problem. There are plenty of places where Rails will work just fine as David points out in his blog.

You need to maintain backwards compatibility better. Admittedly this is the area where PHP has historically done very poorly, but that’s no reason to not one-up them. Also, Rails is admittedly very young as a development platform and you guys have gotten a LOT of attention very early on. Still, with big hype comes big responsibility. You need to keep the momentum going now. This is just dumb. Rails is an incredibly new framework and they have great backwards compatibility. In fact they have full backwards compatibility. If your site doesn't work with the latest version of Rails just stick with the one you are using. You can have hundreds of different versions of Rails installed at the same time and the app can use whatever version is wishes. This is full backwards compatibility.

Officially support shared hosting environments. The feeling I get from the Rails community is that Rails is being pushed as some sort of high-end application system and that makes it ok to ignore the vast majority of user web environments. You simply cannot ignore the shared hosting users. In my opinion, the one thing the PHP people did that got them to where they are today is to embrace shared hosting and work hard to make their software work well within it. That means it has to be very lightweight (it may be too late for that in Rails already!), and it has to ‘plug in’ to a wide variety of operating environments with minimal fuss and hassle. Compatibility work like that is not glamorous, exciting, or fun, but it’s gotta be done. The reason you get the feeling that Rails is some sort of high-end application system is because to some extent you are right. You absolutely can't ignore shared hosting? Really? Seems to have worked OK for Java. Why doesn't DreamHost support Java? Let me guess, because it's too heavy weight? Rails is a full fledged web development framework. Just like Java, it's always in memory so that it can take advantage of being a long running process. This is less than ideal for hosting companies that are trying to sell $5 hosting packages, but for building real web applications this is almost a necessity. I'd say not only CAN they ignore shared hosting companies but they quite successfully are ignore you. Rails doesn't lend itself as well to shared hosting as well as PHP does. It's up to the shared hosting companies to figure that out. That's what YOUR business is. Oh and several hosting companies can and have figured it out so your public rant is really kind of embarrassing for DreamHost.

Tags: rubyonrails litespeed

Annoying Flash Issues

Posted by Sam

So I'm working on the Barkley Holiday site for 2007 and I ran into several frustrating things today. A little background on the site. The backend is written in Ruby on Rails and the frontend is flash based. I use LiteSpeed's excellent web server for the application and web server. The backend of the site is pretty simple. It's using the attachment_fu plugin to upload and resize photos and then simple XML to communicate with the Flash frontend.

The first problem I had today was that Flash couldn't get the XML when running inside IE6 on Windows. It works everywhere else. Grrr. The Flash developer found an article that was mostly wrong, but had just enough truth to help me find the real problem. When using rxml templates Rails will automatically return a content type of 'application/xml'. For whatever reason when you combine this with gzip compression, Flash and IE6 you can run into a situation where IE6 won't push the XML to Flash. If you turn off the compression it works fine. I turned off compression in LiteSpeed for dynamic content and everything worked. I really wanted the compression so I kept poking around to see if I could find another solution. Turns out if you leave compression enabled and change the content type to 'text/xml' then everything works fine. Stupid Internet Explorer! So if you are using Flash with RXML, IE6 and dynamic gzip compression you should set the content type like so. @headers['Content-Type'] = "text/xml"

The next problem I had with Flash was that images weren't being resized with attachment_fu when they were uploaded from the Flash frontend. If I loaded them with the backend HTML interface everything worked as expected. This turned out to be a relatively easy problem, but it still bugs me. Flash doesn't set the correct MIME type when it uploads files. Instead of uploading the files with a MIME type of 'image/jpeg', 'image/jpg' or something sane Flash pushes files up with a generic 'application/octet-stream' MIME type. Attachment_fu was seeing this MIME type and didn't think it was an image so it wouldn't resize it. Since we are only uploading images to this particular application I hacked the attachment_fu plugin to accept 'application/octet-stream' as a valid image MIME type. There might be a better way to do this but I needed it done yesterday so here is the original code found in attachment_fu > lib > technoweenie > attachment_fu.rb. #original code
@@content_types = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg']
And here is the code with the MIME type needed to process Flash uploads. #hacked code
@@content_types = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg', 'application/octet-stream']

I'm not sure if the first problem that I ran into is Flash's fault or IE6, but the second issue definitely seems like a problem with Flash. The browsers push up the MIME type so why can't/doesn't Flash?

Tags: rubyonrails litespeed

Easy Custom Environment in LiteSpeed for Rails

Posted by Sam

Update (8/12/2008)

Thanks to LiteSpeed adding a staging environment this work around is no longer necessary for me, but I'm leaving it here in case others need custom environments besides staging.

Ruby on Rails has three standard environments. Development, test and production. Test mode is also called staging by a lot of people, including myself. Unfortunately, my favorite web server and all around best Ruby on Rails application server, LiteSpeed, doesn't have a test mode. For whatever reason they implemented the development and production modes for Rails but didn't include a test mode. This is annoying because any real application development should be going through some formal or informal QA and this should be happening on a dedicated staging environment.

There are a couple of ways around LiteSpeed's lack of a test mode for Ruby on Rails. One of them is to simply set the RAILS_ENV variable in the environment.rb file like so. # Uncomment below to force Rails into production mode when
# you don't control web/app server and can't set it the proper way
ENV['RAILS_ENV'] = 'test'
I don't like this because if you push this exact same code to production it will override the default value, which should be production. That could cause all kinds of problems. Since I do all my pushes (both personal and professional) straight from subversion I would have to remember to make this change every time I pushed a site update to staging. It just feels wrong.

Another options is to forgo the easy Ruby on Rails setup in LiteSpeed and do a custom setup as described here. But then you will have the problem this guy had. Obviously it's doable but still seems dirty.

I prefer to stick with the standard and obvious way of doing things whenever possible. When you have to quickly migrate a server at 3 in the morning I have learned that keeping things straight forward is the best approach. Sometimes I will go to great lengths to keep something simple when a quick and dirty approach would have sufficed for a while. Keeping things standard and clean is the best approach. So, that being said, this is the approach that I think works best for setting up a test (or staging as we call it) environment in LiteSpeed. Change the environment.rb file in your Rails so that it reads: # Uncomment below to force Rails into production mode when
# you don't control web/app server and can't set it the proper way
ENV['RAILS_ENV'] = 'test' unless ENV['RAILS_ENV']
Basically you are saying if you don't know what your environment should be, set it to test. Now you need to make sure that the RAILS_ENV is not set by LiteSpeed so go to Configuration > Virtual Host Templates > EasyRailsWithSuEXEC > Context > Edit and select the blank option in the Rails Environment section. Restart LiteSpeed and your custom environment should be loaded.

Tags: rubyonrails litespeed

LiteSpeed Ruby on Rails Optimizations

Posted by Sam

LiteSpeed and Ruby on Rails are a dream come true. If you are deploying Rails apps on anything else in a production environment you are nuts. Not only is LiteSpeed/Rails one of the fastest (if not THE fastest) combinations for serving up Rails, it's also by far the simplest. LiteSpeed is also many times faster than Apache at serving regular files. Benchmark it for yourself and you'll see that it is indeed many times faster. So like I said, you are nuts if you are using anything else for your Rails applications.

One of the things that I do find annoying though is that by default LiteSpeed shuts down Rails applications after one minute of inactivity. Which means that if somebody hits your site every two minutes they have to wait for LiteSpeed to reload your application every time they hit a dynamic page. Which, even on a fast machine, might take a second or more. To change this in LiteSpeed 3.2.2 go to the Ruby Rails tab and change LSAPI_MAX_IDLE to the same value as "Max Idle Time". I set mine to 3600 seconds (one hour). LSAPI_MAX_IDLE=3600 After one hour if nobody hits your Rails site then it will unload and free up memory. Of course all of my sites are monitored with Nagios every five minutes so there is always at least one Rails instance running. Check out LiteSpeed's Ruby LSAPI page for more information on tuning Rails on LiteSpeed.

Tags: litespeed rubyonrails