Search code examples
ruby-on-railsrubyrakecapistrano

Rails - Run Rake tasks with Capistrano


Im scratching my head here wondering if I'm barking up the wrong tree. I have a server which I've deployed a Rails app onto using Capistrano. Recently I added a new data type to one of the models, and now I need to run a Rake task to update the existing records.

After a lot of Googling I'm starting to wonder if people use Rake tasks with Capistrano. Some forum posts from 2013 or so mention that Capistrano supports the .rake extension. Whereas other posts I've found indicate that Capistrano has its own task automation system, and is incompatible with rake.

I found Cape, but I'm unsure if this is what I'm looking for as it seems to convert Rake tasks into cap recipes. Its possible I'm mistaken on this point, I really don't have any experience working with Capistrano or even working in the full stack spectrum.

What I'm wondering is this: How do I run a simple Rake task on my remote server?

Some quick points for clarity, I've installed the app on the latest Ubuntu LTS, 14.10 if memory serves. I followed the tutorial found here. I have full sudo access and I can ssh into the server.

thanks in advance for helping a noob


Solution

  • If you need to update models, you can of course write a Rails migration - this will ensure that it's run if it hasn't been run yet.

    The easiest way to execute a rake task on the server would be just via ssh if it's a one-time task. See the last paragraph in the tutorial you mentioned:

    cd /opt/www/testapp/current ; bin/rake RAILS_ENV=production db:seed
    

    To answer your original question about rake: you can execute rake tasks via capistrano similar to how you would execute it locally, only within the capistrano script. Here's an example:

    deploy.rb:

    namespace :rake do
      desc "My task"
      task :my_task do
        on roles(:app) do
          within "#{current_path}" do
            with rails_env: :production do
              execute :rake, "my_task"
              # !!!see NOTE at end of answer!!!
            end
          end
        end
      end
    end
    

    You can view all your cap tasks via cap -T locally. The capistrano task I wrote above should show up as cap tasks:my_rake_task.

    If you want to be ably to run any available rake task without configuring, do the following:

    namespace :rake do
      desc "Invoke rake task"
      task :invoke do
        on roles(:app) do
          within "#{current_path}" do
            with rails_env: :production do
              execute :rake, ENV['task']
              # !!!see NOTE at end of answer!!!
            end
          end
        end
      end
    end
    

    Then you can write:

    cap production deploy:invoke task=my:rake:task
    

    NOTE: you might want to replace the execution line with

    run "bin/rake RAILS_ENV=#{rails_env} #{ENV['task']}"
    

    to use the same syntax as the tutorial (without the binstubs you might need to configure capistrano/bundler and capistrano/rbenv first ...)