Yesterday, we had to restore the production DB from a backup, since we ran "rake db:schema:load" in production by mistake. To avoid that problem in the future, I decided to disable that task, and others than can screw with the DB, in production.
It was a matter of adding a prerequisite to those dangerous tasks, that checks if they are being run in production, and exit accordingly. I also added a flag to override this safeguard, together with some code to backup the DB. To do this, I added the following code to lib/tasks/disable_db_tasks_on_production.rake:
DISABLED_TASKS = [ 'db:drop', 'db:migrate:reset', 'db:schema:load', 'db:seed', # ... ] namespace :db do desc "Disable a task in production environment" task :guard_for_production do if Rails.env.production? if ENV['I_KNOW_THIS_MAY_SCREW_THE_DB'] != "1" puts 'This task is disabled in production.' puts 'If you really want to run it, call it again with `I_KNOW_THIS_MAY_SCREW_THE_DB=1`' exit else require 'heroku' puts 'Making a backup of the database, just in case...' puts `heroku pgbackups:capture` end end end end DISABLED_TASKS.each do |task| Rake::Task[task].enhance ['db:guard_for_production'] endIt would be nice to add something like this to the default Rails app, since, if you are reading this, chances are high that is too late for this to protect you by now :)
Some feedback from reddit's darkphnx, nice to know we're not the only ones :)
Initially you think "What sort of moron would write db:schema:load" on a production machine, but it's not that simple.
Plenty of application hosting systems will look at what sort of application you're deploying and make assumptions about what commands should be run on first deployment. Very often one of these is "rake db:schema:load".Let's say you're deploying to a new hosting environment, but pointing to an existing database. If you forget to check what commands are going to run on first deployment deployment it will come along and be very helpful "oh, this is the first time you've deployed this app, I'll load the database schema for you". db:schema:load drops any existing tables.If you're not watching the deployment carefully, the first time you'll know is when the deployment is complete all your data is gone. If you're lucky you were watching and you've only lost a couple of tables.Source: Did exactly this, had to restore a 50GB table from backup.
Excellent idea, and I plan to start using it right away.
ReplyDeleteYou didn't say where to place this code - I'm assuming Rakefile, but it would probably be a good idea to clarify that.
Just clarified it, you need to add it to a new rake task, lib/tasks/disable_db_tasks_on_production.rake for example. Happy you like it!
ReplyDeletethanks!!!! make my day!
ReplyDeleteYou shouldn't need to require the heroku gem if you're just going to shell out to the heroku command line app.
ReplyDeleteThe heroku plugin is, ironically, not available in heroku, so you need the gem there.
DeleteBig like!
ReplyDeleteuseful, thank you! I hope it'll make into rails
ReplyDeletethese are the ones I've used:
DISABLED_TASKS = [
'db:drop',
'db:drop:all',
'db:fixtures:load',
'db:migrate:reset',
'db:purge',
'db:purge:all',
'db:reset',
'db:schema:load',
'db:seed',
'db:setup'
'db:structure:load'
]
Very very good idea! Why don't you send a patch to rails right now ;)
ReplyDeleteThanks friends, for providing such enlightening data.
ReplyDeletemediaonlines.com
You probably know as well as I do that SEO isn’t like Paid Search, where you can bring in leads, at volume, pretty quickly.
ReplyDeletexenforo custom bbcode
Male Sex Toys
ReplyDeleteWaooow!!! Magnificent blogs, this is what I wanted to search. Thanks buddy