Run seed data only on first Docker instance up

Swapnil Gourshete | November 22, 2019 | 2 Minute Read

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 -
During deployment

  • 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 rails db:migrate.

Cheers! 🍻🍻