Run seed data only on first Docker instance up
Q: Do we need to run rails db:seed, rails db:migrate every time the deployment happen?
Ans - Absolutely no. rails db:seed should only run for the first time i.e. first deployment. But migrations should be run on every deployments.
So here is what we need - Run seed data only for first deployment. We will consider here containerised architecture.
Here are steps -
- Check if db exists
- If yes, then run rails db:migrate
- If no, then run rails db:create && rails db:migrate && rails db:seed
How to determine if db exists during deployment?
Ans - After some googling, found out that a rake task can be written to determine if db exists
namespace :db do desc "Checks to see if the database exists" task :exists do begin Rake::Task['environment'].invoke ActiveRecord::Base.connection rescue exit 1 else exit 0 end end end
This task tries to establish connection with the database, if exception occurs then return with exit 1. Exception occurred, here, means the database does not exists. And no exception means connection established successfully and return with exit 0. To summarise,
if db does not exists then exit 1 if db exists then exit 0
Run seed data if db:exists, How?
Ans - In deployment script, the conditional bash logic can be executed like
args: [ "-c", "env && bundle exec rake db:exists; DB_EXISTS=$?; [[ $DB_EXISTS = 1 ]] && (rails db:create db:migrate db:seed) || (rails db:migrate)" ]
bundle exec rake db:exists; DB_EXISTS=$?; [[ $DB_EXISTS = 1 ]] && (rails db:create db:migrate db:seed) || (rails db:migrate)
This makes call to rake task above. Then collects its output into a variable DB_EXISTS. Then check if value of DB_EXISTS is equal to 1(which means db does not exists, according to our above assessment), IF YES THEN RUN
rails db:create db:migrate db:seed, ELSE run