Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I perform Laravel Artisan migrations on AWS Elastic Beanstalk?

I have a Laravel installation and have set up three environments with their own corresponding config directories:

  • local
  • staging
  • production

I use php artisan migrate:make create_users_table etc as described here to create database migrations.

In my local environment I use Vagrant and a simple MySQL server setup, and on staging & production I use AWS RDS.

To configure database access for the staging environment I have a app/config/staging/database.php file with settings like this:

...
"mysql" => array(
    "driver" => "mysql",
    "host" => $_SERVER["RDS_HOSTNAME"],
    "database" => $_SERVER["RDS_DB_NAME"],
    "username" => $_SERVER["RDS_USERNAME"],
    "password" => $_SERVER["RDS_PASSWORD"],
    "charset" => "utf8",
    "collaction" => "utf8_unicode_ci",
    "prefix" => "",
),
...

I use git to deploy the app with git aws.push as described here.

The question is: How do I run the migration on my staging (and later production) EBS server when deploying?

like image 668
oskarth Avatar asked Apr 09 '14 21:04

oskarth


2 Answers

Worth mentioning here if people are using a dockerised container to run their application on Beanstalk, you will have to run this inside the container.

files:
    "/opt/elasticbeanstalk/hooks/appdeploy/post/98_build_app.sh":
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/usr/bin/env bash
            echo "Running laravel migrations" >> /var/log/eb-activity.log
            docker exec $(docker ps -qf name=php-fpm) sh -c "php artisan --env=staging migrate --force || echo Migrations didnt run" >> /var/log/eb-activity.log 2>&1

The problem is the container name changes each time.

So the docker ps -qf name=php-fpm part is just going to get a container with the container name containing php-fpm. So replace that with something else that matches which container you want to run it on.

Also use --force because otherwise, its going to try and wait for a prompt

like image 153
Oli Girling Avatar answered Sep 23 '22 02:09

Oli Girling


I solved it by creating a new directory in the root of my project named .ebextensions. In that directory I created a script file my-scripts.config:

.ebextensions/
    my-scripts.config
app/
artisan
bootstrap
...

The file my-scripts.config gets executed when EBS deploys, is a YAML file and looks like this:

container_commands:
    01-migration:
        command: "php /var/app/ondeck/artisan --env=staging migrate"
        leader_only: true

Add the directory and file to git, commit, and run git aws.push and it will migrate.

Explanations on how stuff in .ebextensions works can be found here.

The path /var/app/ondeck is where your application lives when your script runs, it will afterwards be copied into /var/app/current.

The artisan option --env=staging is useful for telling artisan what environment it should run in, so that it can find the correct database settings from app/config/staging/database.php

If you need a quick and dirty way to log why the migrate command fails you might want to try out something like "php /var/app/ondeck/artisan --env=staging migrate > /tmp/artisan-migrate.log" so that you can log into your ec2 instance and check the log.

like image 26
oskarth Avatar answered Sep 21 '22 02:09

oskarth