I encountered this same problem when using Elastic Beanstalk with an external Amazon RDS database. Basically, the problem is that the Elastic Beanstalk pre-deployment scripts will attempt to migrate the database before it even exists.
There are two ways I discovered for how to solve this.
The first way is to set the RAILS_SKIP_MIGRATIONS=true
environment variable on your app configuration. This should allow you to at least get the codebase deployed. After that, you can use eb ssh
to shell into the app, browse to the /var/app/current/
folder, and manually run bundle exec rails db:create
and bundle exec rails db:migrate
.
Another way to solve the problem is to create an app pre-deploy shell script hook file in the /opt/elasticbeanstalk/hooks/appdeploy/pre/ folder.
I used the /opt/elasticbeanstalk/hooks/appdeploy/pre/12_db_migration.sh file as reference, and here's what I came up with.
Create a file in your project called /.ebextensions/0001_rails_db_create.config
, with the following contents:
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/11_create_db.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
set -xe
EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)
. $EB_SUPPORT_DIR/envvars
RAKE_TASK="db:create"
. $EB_SCRIPT_DIR/use-app-ruby.sh
cd $EB_APP_STAGING_DIR
if su -s /bin/bash -c "bundle exec $EB_SCRIPT_DIR/check-for-rake-task.rb $RAKE_TASK" $EB_APP_USER; then
if [ "$RAILS_SKIP_DB_CREATE" = "true" ]; then
echo "Skipping database creation (RAILS_SKIP_DB_CREATE=true)."
else
su -s /bin/bash -c "leader_only bundle exec rake db:create" $EB_APP_USER
fi
else
echo "No $RAKE_TASK task in Rakefile, skipping database creation."
fi
Commit that file to your git repo and then run eb deploy
.
This should create the shell script hook file which will create the rails db if it doesn't exist. The database migration shell script hook file should run immediately afterwards, since its name starts with the number 12.
Once this script is in place, if you ever want to bypass it, you can set the RAILS_SKIP_DB_CREATE=true
environment variable on your app.
/var/log/eb-activity.log
file so that we can help figure out why your migration failed. – Brianrake db:migrate
works correctly locally. – progfan