Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Agile Web Development With Rails, 2nd Edition (2006).pdf
Скачиваний:
30
Добавлен:
17.08.2013
Размер:
6.23 Mб
Скачать

This chapter was written by James Duncan Davidson (http:// duncandavidson.com). Duncan is an independent consultant, author, and—oddly enough—freelance photographer.

Chapter 27

Deployment and Production

Deployment is supposed to mark a happy point in the lifetime of your application. It’s when you take the code that you’ve so carefully crafted and upload it to a server so that other people can use it. It’s when the beer, champagne, and hors-d’oeuvres are supposed to flow. Shortly thereafter, your application will be written about in Wired magazine, and you’ll be an overnight name in the geek community. Unfortunately, it doesn’t always play out that way. In contrast with how easy it is to create a Rails application, deploying that application can be tricky, irritating, and sometimes downright infuriating. There are a lot of decisions to be made and many trade-offs to weigh in making those decisions. In short, deployment is when you leave the comfortable, opinionated world of Rails development and enter into a much more chaotic world where many answers are right and which one is right depends on the situation.

To be fair, deploying web-based applications is always a DIY (Do It Yourself ) affair. Everyone has their own unique network setup and different requirements for database access, data security, and firewall protections. Depending on your needs and budget, you might be deploying to a shared hosting provider, a dedicated server, or even a massive cluster of machines. And, if your application operates in an area where either industry or government standards apply—such as Visa CISP when you accept online payments, or HIPAA if you work with medical patient data—you’ll have lots of external, and sometimes conflicting, forces affecting how your application is deployed that are outside of your control.

The good news is that you don’t have to start off by trying to set up the perfect production deployment from the get go. Instead, you should work your way up to it. You should start doing your first deployments as early in the development process as possible. This will help you learn how to deploy your application in such a way that it is secure and meets all applicable requirements before you have to do it for real customers. It’s like learning how to walk before you run.

STAR TING EARLY 614

This chapter will show you how to get started with these initial deployments and give you some tips on issues to look for on your way to a real production deployment.

27.1Starting Early

The trick to becoming competent with deploying Rails applications is to start early. As soon as you are ready to show your budding Rails application to somebody else, you are at the point where you should set up a deployment server. This doesn’t have to be your final deployment environment. You don’t need a cluster of fast heavy-duty industrial-strength servers. You need only a modest machine that you can dedicate to the purpose of hosting your developing application. Any spare machine you have sitting around, such as that G4-based cube in the corner, will work just fine.

What are the benefits to starting early? Well, first of all, you’ll get yourself into the rhythm of code, test, commit, and deploy. This is the rhythm that you’ll be in at some point with your application, and you’ll serve yourself well by getting into it sooner in the development of your application rather than later. You’ll be able to identify deployment issues that will affect your application and gain a lot of practice dealing with them. These issues could revolve around migrations, data importing, or even permissions on files. Each application seems to exhibit its own little quirks on deployment. Finding out what these quirks are early means that you don’t find out what they are right after you launch your site publicly and start needing to push out quick deployments to fix bugs and add features.

Setting up an early deployment environment also means that you’ll have a running server that you can let your client, boss, or trusted friends check out the progress of the application on. As agile developers know, the more feedback users can give you early in the development process, the better. You’ll be able to get important feedback by seeing what these early users think of your application, the problems they have, and even their ideas of how to make your application better. They’ll help you identify what you are doing right and what features need improvement or even removal.

Starting early means that you can practice using migrations to modify and change your database schemas with already existing data. When you work solo on your own machine, problems can creep in with revising the way an application upgrades itself. When you are working with others by deploying to a common server, you’ll gain experience in how to move an application forward seamlessly.

Lastly—and this is the most important benefit—you’ll know that you’re in a position to deliver your application to your users. If you spend four months

Report erratum

HOW A PRODUCTION SERVER WORKS 615

Rails

The

Apache,

Internet

Lighttpd, or Rails

Similar

Rails

Figure 27.1: How a Deployed Rails Application Works

working 80 hours a week on your application, but never deploy it, and then decide to put it in production tomorrow, chances are good that you’ll run into all sorts of problems getting it live. And, you’ll have issues keeping it going, never mind updating it. However, by setting up deployments as early as possible, you’ll know that you can deliver your application at a moment’s notice.

27.2How a Production Server Works

So far, as you’ve been developing a Rails application on your local machine, you’ve probably been using WEBrick or Mongrel when you run your server. For the most part, it doesn’t matter. The script/server command will sort out the most appropriate way to get your application running in development mode on port 3000. However, a deployed Rails application works a bit differently. You can’t just fire up a single Rails server process and let it do all the work. Well, you could, but it’s far from ideal. The reason for this is that Rails is single-threaded. It can work on only one request at a time.

The Web, however, is an extremely concurrent environment. Production web servers, such as Apache, Lighttpd, and Zeus, can work on several requests— even tens or hundreds of requests—at the same time. A single-process, singlethreaded Ruby-based web server can’t possibly keep up. Luckily, it doesn’t have to keep up. Instead, the way that you deploy a Rails application into production is to use a front-end server, such as Apache, to handle requests from the client. Then, you use either FastCGI or HTTP proxying to send requests that should be handled by Rails to one of any number of back-end application processes. This is shown in Figure 27.1.

This setup allows Rails to scale to multiple application servers. A single frontend web server can distribute requests to any number of Rails processes running on any number of back-end machines. And, since Rails is built on an architecture that assumes that all state is held outside of the application (typically in the database layer but also using the filesystem and possibly shared

Report erratum

HOW A PRODUCTION SERVER WORKS 616

memory caches), this basic architecture means that Rails applications can scale up to the point at which your database falls over. If a slowdown happens in the Rails application layer, you can simply add another server (or three) and scale capacity accordingly.

The downside with this setup is that it requires the use and configuration of multiple moving parts. Not only do you need a front-end web server installed, but you also need to install your application as well as set up the scripts that will start up your back-end application servers. We’ll see how to do this in just a bit.

FastCGI vs. Proxying Requests

When Rails first came out, the most-used high-performance option for running Rails application processes was FastCGI. In fact, the first edition of this book recommended it, saying that using FastCGI was like strapping a rocket engine on Rails. FastCGI uses long-running processes that can handle multiple sequential requests. This means that the Ruby interpreter and Rails framework is loaded once per process and, once loaded, can turn around requests for the host web server quickly.

However, FastCGI came with lots of issues. FastCGI dates back to the mid1990s. Until Rails came along, it had languished in relative obscurity. Even after Rails brought FastCGI back to the public attention, production-level, quality FastCGI environments were few and far between. Many developers, ourselves included, have deployed applications using every possible combination of web server and FastCGI environment and have found serious issues with every single one of them. Other developers have deployed FastCGI-based solutions with nary a problem. But enough people have seen enough problems that it has become clear that it’s not a great solution to recommend.

In 2006, as more and more Rails developers cast about for a better solution, an alternative emerged straight from HTTP. Many developers found they could get excellent and flexible results by proxying HTTP requests from a scalable frontend server, such as Apache, to a set of back-end Ruby-based Rails application servers. This alternative came of age at the same time as Mongrel, a mostly Ruby web server written by Zed Shaw that performed well enough to be used as a cog in this kind of system setup.

The solution of using HTTP proxying also plays into the strengths of the many different kinds of load balancers that are available. Both Apache and Lighttpd feature the ability to act as a front end to a fleet of back-end application servers. However, you can also use raw HTTP load balancers (such as Pound) or even hardware based load-balancers to forward requests directly to any number of Rails instances.

Report erratum

COMPARING FRONT -END WEB SERVERS 617

What About CGI?

If you dig around in your Rails application, you’ll notice that there is a public/dispatch.cgi file. This file allows you to run your Rails application as a CGI application. However, you really, really don’t want to do this. Running a Railsbased application as a CGI is an exercise in patience because each request loads up a fresh Ruby interpreter as well as loads the entire Rails framework. Loading up a Ruby interpreter isn’t too big a deal, but it takes a while to load in all the functionality that Rails brings. The time to process a typical request can venture into the realm of seconds even on the fastest of machines.

The best advice when it comes to CGI and Rails: Don’t do it. Don’t even think about it. It’s not a reasonable option and, in our opinion, should be removed from a default Rails installation.

Possibly the most compelling advantage of using HTTP proxying to connect the various web server tiers of the application stack is that it is future proof and extensible. You can insert other web-based application solutions (such as those based on Python, C, Erlang, or any other language) into your overall infrastructure and weave it into your web application. And, you can have components of your application call other components using direct HTTP calls. This level of integration ventures off into the Service-Oriented Architecture (SOA) territory, on which reams have been written (elsewhere).

In short, FastCGI is a rocket that sometimes blows up in strange ways on the launching pad. Using proxy setups to talk to HTTP-speaking Rails application processes is the general direction that the community is moving in. When setting up your own deployment environment, you should follow suit—and it’s how we’ll show you how to deploy your application.

27.3Comparing Front-End Web Servers

For most purposes, especially for an initial deployment, there are two primary front-end web servers that you’ll want to consider: Apache and Lighttpd. Once you’ve moved your application into a live public environment, there are alternatives to these two, including Pound and other lightweight HTTP-based load balancers. But, making a choice at this level doesn’t paint you into a corner. You can easily move between Apache, Lighttpd, and Pound without changing your Rails code at all.

Apache: An Industry Standard

Apache is practically ubiquitous, and for two very good reasons: it’s incredibly flexible and has reasonable performance characteristics. It runs on just about

Report erratum