Deploying a Rails app with Thinking Sphinx

If you’re using or investigated full-text search options you’ve likely come across some really great comments about Sphinx. It’s fast and has a lot of great features.

For a Rails application, there are a few plugins which make it easy to use Sphinx. The main two at this time are UltraSphinx and Thinking Sphinx. I chose Thinking Sphinx for my project mostly because it can keep the Sphinx indexes current in close to real-time as things are added to the database using delta indexes. UltraSphinx can use delta indexes, but doesn’t seem to be as real-time at updating them as ThinkingSphinx. If I’m wrong, please correct me.

Now that I’m using Thinking Sphinx I eventually had to deploy it. Since I didn’t find much info about deploying it using “Capistrano”:http://capify.org here’s what I did to get deployments running smoothly.

Sphinx Index Location

While Sphinx is fast, you still probably don’t want to have to re-create your indexes on every deployment. I have my indexes getting created into my shared path and an :after_symlink task deals with making sure my app is pointing to the right place.

  desc "Re-establish symlinks"
  task :after_symlink do
    run <<-CMD
      rm -fr #{release_path}/db/sphinx &&
      ln -nfs #{shared_path}/db/sphinx #{release_path}/db/sphinx
    CMD
  end

Stopping and Starting Sphinx

Thinking Sphinx follows convention rather than configuration. Before any index Thinking Sphinx re-creates your configuration file based on the information in your models. Since it re-creates it, I have it ignored in my repository. As such, the configuration file does not exist on a fresh deploy.

I created some tasks to stop, start and restart Sphinx using the rake commands that come with Thinking Sphinx. One problem I ran into right away was the absence of the config/production.sphinx.conf file that’s expected when you run the thinking_sphinx:start task. Luckily, there’s another rake task called thinking_sphinx:configure which re-creates the configuration file without performing a full index.

While there is a thinkning_sphinx:restart task, that doesn’t give me the opportunity to re-create the config file prior to starting Sphinx up again.

  desc "Stop the sphinx server"
  task :stop_sphinx , :roles => :app do
    run "cd #{current_path} && rake thinking_sphinx:stop RAILS_ENV=production"
  end
    
  desc "Start the sphinx server" 
  task :start_sphinx, :roles => :app do
    run "cd #{current_path} && rake thinking_sphinx:configure RAILS_ENV=production && rake thinking_sphinx:start RAILS_ENV=production"
  end
  
  desc "Restart the sphinx server"
  task :restart_sphinx, :roles => :app do
    stop_sphinx
    start_sphinx
  end  

Restarting the App

Now that the Sphinx tasks are there, you just have to update the applications’s :restart task to restart Sphinx when you restart your app.

  desc "Restart mongrel"
  task :restart, :roles => :app do
    restart_sphinx
    sudo restart_mongrel
  end

A full version of the example deploy.rb is pastied.

Commenting has expired for this post.