10 Comments

Run a Local Rails Script on Heroku

Heroku provides a convenient command line interface for executing snippets of Ruby code remotely. One-liners can easily be piped into the heroku run console command. But what about much longer scripts that you write locally and want to execute in a remote Heroku environment? In this post, I’ll show you how to execute a long Ruby/Rails script in a remote Heroku environment.

One-Liner

The run console command will read input from stdin and pass it to the remote console session. Knowing this, you can run a simple Rails query:


echo "puts User.count" | heroku run console --app=my-heroku-app

The result will be displayed in the terminal, but you’ll still be in the Heroku console session. One way to avoid that would be to force the session to end by tacking on an exit to your one-liner.


echo "puts User.count; exit" | heroku run console --app=my-heroku-app

Now the result is displayed, and the console session exits immediately.

Long Scripts

I wanted to run a much longer script (several thousand lines) using this same technique, but whenever I’d try, it would always hang part-way through the script, never completing.

My teammate Brian Vanderwal pointed out the --no-tty argument, and that did the trick! By including that argument, I can pipe (or redirect) an arbitrarily long Ruby script into a Heroku console. And as an added bonus, when you specify the --no-tty argument, you no longer need the exit at the end.


echo "puts User.count" | heroku run console --app=my-heroku-app --no-tty

or


cat some_script.rb | heroku run console --app=my-heroku-app --no-tty

Conclusion

For years, I’ve known about the ability to run scripts that are checked into the repository using the heroku command line tool.


heroku run bundle exec rails runner ./scripts/script.rb -a my-heroku-app

But there are some cases where you want to execute code in the production environment without doing a full production deploy first. In those cases, the --no-tty argument to the heroku run console command is exactly what you need.