views:

2021

answers:

5

I'd like to set up a staging server for a Rails app. I use git & github, Cap, and have a VPS with Apache/Passenger. I'm curious as to the best practices for a staging setup, as far as both the configuration of the staging server as well as the processes for interacting with it. I do know it should be as identical to the production server as possible, but restricting public access to it will limit that, so tips on securing it only for my use would also be great.

Another specific question would be whether I could just create a virtual host on the VPS, so that the staging server could reside alongside the production one. I have a feeling there may be reasons to avoid this, though.

+3  A: 

I guess it depends if the staging server needs be accessible by anyone but you. If other people need to be able to access it then you would need another small slice somewhere and then you can use htaccess, or firewall rules to limit who gets access to it. If no one else needs to access it I would suggest using VMWare. You can run it on your own machine, or a spare box you have around, or a very cheap PC. We use the free VMWare Server 2 for our staging and deployment test servers and it works great. It also makes it very easy to create new test servers by just duplicating your base VM setup. If you are on a Mac you can use VMWare Fusion, costs money, but I have to use it already to test IE.

ScottD
Thanks a lot -- I've clarified about who will need it. It's only me, but it'll also need to communicate with a third-party payment site.
fig
That should work fine. You can configure the VMWare machines to have access to the internet.
ScottD
+1  A: 

Use two separate servers (VPS or whatever) as similar as you can make them (hardware and software) at the base image. Automate all configuration of your production environment so nothing is done by hand. Use that automation to produce a staging server that's identical to your production environment. Maintain the automation to ensure both environments stay in sync and can be replicated on demand.

Solves both your staging-out-of-sync problem and your first-order scaling problem.

As far as cost goes, VPSes are cheap as chips. The number of production downtime-inducing failures you'll avoid by having a staging server will pay for your staging environment in no time (unless you're not actually making any money at all, in which case downtime isn't so much of a problem and you can go nuts with the breakage).

womble
+2  A: 

I'll probably get shot for saying this, but for small sites on tight budgets, I see nothing wrong with running the staging site right alongside the production one.

You're using Rails, Apache, and Passenger. Set up different Rails configurations (and databases), and set each one up as a named VirtualHost. Protect one with htaccess. Create an A record from your domain (staging.*) and point it there.

Sure, they're not completely insulated from each other. You might crash everything. Oops! It probably won't matter. :)

Ian Terrell
+6  A: 

Cheap and Easy answer:

1) Point staging.domainname.com at your VPS.

2) Add in a virtual host for staging, pointing to the staging copy of the app.

3) Add in a staging environment setting. (Did you know you could define new environments in Rails? Fun stuff!) I think this is as simple as copying production.rb to staging.rb and tweaking as necessary, plus updating database.yml.

4) In ActionController, add in code similar to the following

   if (ENV["RAILS_ENV"] == "staging")
     before_filter :verifies_admin
   end

Where verifies_admin can be anything you want. I suggest using HTTP basic authentication -- cheap and easy.

def verifies_admin
  authenticate_or_request_with_http_basic do |username, password|
    username == "foo" && password == "bar"
  end
end

Note that this may bork your connection to that payment site if they are making inbound requests to you, although that is simple enough to fix (just turn off the before_filter for the appropriate controllers and/or actions.)

Better answer:

1) Buy a second VPS configured from the same image as your regular VPS, and/or configured from the same install-from-the-bare-metal script (I like Capistrano & Deprec for this).

2) Point staging.domainname.com at it.

3) Otherwise its the same as the other option.

Things to think about:

1) Should I have a staging database as well? Probably, especially if you're going to be testing schema changes.

2) Should I have some facility for moving data between the staging and production systems?

3) Can catastrophic failure of my staging application take down the main application? Best hope the answer is no.

Patrick McKenzie
This post is a bit old, but you can take Patrick's plans and apply them to Amazon EC2's new Microinstances which run about $15/mo and are amazingly a good deal for 512mb+ of memory on a burstable machine. One of the nice things is that the image you use on a regular EC 2, or other machine, can easily be put on a Microinstance. I've got a Large instance running w/ a Micro for staging and a micro for playground.
Mike
+1  A: 

I would add to this that Jamis Buck, who created Capistrano, also created a gem specifically for setting up multi-stage environments with Capistrano. You can do it without the gem, but the gem makes it even easier. You can find his post on it with instructions here: http://weblog.jamisbuck.org/2007/7/23/capistrano-multistage

There's also a very helpful article in the Pragmatic Programmer book "Advanced Rails Recipes" that walks you through exactly how to set this up. I found that the answers to this post, combined with the Rails Recipes book made this incredibly easy to set up.

StackOverflow won't let me add another link, but if you google Advanced Rails Recipes, the book is the first result.

MikeH