Run seed data only on first Docker instance up

Swapnil Gourshete Swapnil Gourshete Follow Nov 22, 2019 · 2 mins read
Share this

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
          exit 1
          exit 0

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! 🍻🍻

Swapnil Gourshete
Written by Swapnil Gourshete Follow
Hi I am Swapnil, a Software Engineer and computer science enthusiastic