Rails migration on ECS

Viewed 2902

I am trying to figure out how to run rake db:migrate on my ECS service but only on one machine after deployment.

Anyone has experience with that?

Thanks

3 Answers

I built a custom shell script to run when my docker containers start ( CMD command in docker ):

#!/bin/sh

web_env=${WEB_ENV:-1}
rails_env=${RAILS_ENV:-staging}
rails_host=${HOST:-'https://www.example.com'}

echo "*****************RAILS_ENV is $RAILS_ENV default to $rails_env"
echo "***************** WEB_ENV is $WEB_ENV default to $web_env"

######## Rails migration ################################################
echo "Start rails migration"
echo "cd /home/app/example && bundle exec rake db:migrate RAILS_ENV=$rails_env"

cd /home/app/example
bundle exec rake db:migrate RAILS_ENV=$rails_env
echo "Complete migration"


if [ "$web_env" = "1" ]; then

  ######## Generate webapp.conf##########################################
  web_app=/etc/nginx/sites-enabled/webapp.conf

  replace_rails_env="s~{{rails_env}}~${rails_env}~g"
  replace_rails_host="s~{{rails_host}}~${rails_host}~g"

  # sed: -i may not be used with stdin in MacOsX
  # Edit files in-place, saving backups with the specified extension.
  # If a zero-length extension is given, no backup will be saved.
  # we use -i.back as backup file for linux and
  # In Macosx require the backup to be specified.
  sed -i.back  -e $replace_rails_env -e $replace_rails_host $web_app
  rm "${web_app}.back" # remove webapp.conf.back cause nginx to fail.
  # sed -i.back  $replace_rails_host $web_app
  # sed -i.back  $replace_rails_server_name $web_app

  ######## Enable Web app ################################################
  echo "Web app: enable nginx + passenger: rm -f /etc/service/nginx/down"
  rm -f /etc/service/nginx/down

else
  ######## Create Daemon for background process ##########################
  echo "Sidekiq service enable: /etc/service/sidekiq/run "
  mkdir /etc/service/sidekiq
  touch /etc/service/sidekiq/run
  chmod +x /etc/service/sidekiq/run

  echo "#!/bin/sh" > /etc/service/sidekiq/run
  echo "cd /home/app/example && bundle exec sidekiq -e ${rails_env}" >> /etc/service/sidekiq/run
fi

echo ######## Custom Service setup properly"

What I did was to build a docker image to be run as a web server ( Nginx + passenger) or Sidekiq background process. The script will decide whether it is a web or Sidekiq via ENV variable WEB_ENV and rails migration will always get executed.

This way I can be sure the migration always up to date. I think this will work perfectly for a single task.

I am using a Passenger docker that has been designed very easy to customize but if you use another rails app server you can learn from the docker design of Passenger to apply to your own docker design.

For example, you can try something like:

In your Dockerfile:

CMD ["/start.sh"]

Then you create a start.sh where you put the commands which you want to execute:

start.sh

#! /usr/bin/env bash

echo "Migrating the database..."
rake db:migrate
Related