Skip to content

Instantly share code, notes, and snippets.

@zealot128
Last active March 31, 2023 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zealot128/6ce2c47fe288aacfee97f09cd01ed630 to your computer and use it in GitHub Desktop.
Save zealot128/6ce2c47fe288aacfee97f09cd01ed630 to your computer and use it in GitHub Desktop.
Rails Rake task for easy Postgres database dumping and cleanup of old dumps
# https://gist.github.com/amit/45e750edde94b70431f5d42caadee423
namespace :db do
DEFAULT_BACKUP_DIR = "#{Rails.root}/tmp/backups"
BACKUP_DIR = ENV['DB_BACKUP_DIR'].presence || DEFAULT_BACKUP_DIR
KEEP = ENV['DB_BACKUP_KEEP'].present? ? ENV['DB_BACKUP_KEEP'].to_i : 7
desc "Dumps the database to backups"
task dump: :environment do
cmd = nil
with_config do |_app, host, db, user, passw, port|
file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{db}.sql.gz"
opts = "-d #{db}"
if host.present?
opts += " -h #{host}"
end
if user.present?
opts += " -U #{user}"
end
if port.present?
opts += " -p #{port}"
end
cmd = "pg_dump #{opts} | gzip > #{backup_directory}/#{file_name}"
if passw.present?
cmd = "PGPASSWORD=#{passw} #{cmd}"
end
end
if Rake.application.top_level_tasks == ['db:dump']
puts cmd
exec cmd
else
sh cmd
end
end
desc "Cleanup the database backups, keeping #{KEEP} most recent"
task cleanup: :environment do
files = Dir.glob("#{backup_directory}/*.{dump,sql,tar,dir}.gz")
files.sort_by! { |f| -File.ctime(f).to_i }
to_cleanup = files.drop(KEEP)
if to_cleanup.any?
puts "rm #{to_cleanup.map { |i| File.basename(i) }.join(' ')}"
FileUtils.rm(to_cleanup)
end
end
task :dump_and_cleanup => [:dump, :cleanup]
private
def backup_directory
FileUtils.mkdir_p(BACKUP_DIR)
BACKUP_DIR
end
def with_config
yield Rails.application.class.module_parent_name.underscore,
ActiveRecord::Base.connection_db_config.host,
ActiveRecord::Base.connection_db_config.database,
ActiveRecord::Base.connection_db_config.configuration_hash[:username],
ActiveRecord::Base.connection_db_config.configuration_hash[:password],
ActiveRecord::Base.connection_db_config.configuration_hash[:port] || 5432
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment