如何在AWS Elastic Beanstalk上执行Laravel Artisan迁移?

16

我有一个Laravel安装,并设置了三个相应的配置目录的环境:

  • 本地
  • 预备环境
  • 生产环境

我使用如此描述的php artisan migrate:make create_users_table等命令在这里来创建数据库迁移。

在我的本地环境中,我使用Vagrant和简单的MySQL服务器设置,在预备环境和生产环境中,我使用AWS RDS。

要为预备环境配置数据库访问,我有一个像这样的app/config/staging/database.php文件:

...
"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" => "",
),
...

我使用git进行应用部署,按照这里的描述,使用git aws.push命令。

问题是:在部署时如何在我的测试(以及后来的生产)EBS服务器上运行迁移?

3个回答

30
我通过在项目根目录中创建一个名为.ebextensions的新目录来解决了这个问题。在该目录中,我创建了一个名为my-scripts.config的脚本文件:
.ebextensions/
    my-scripts.config
app/
artisan
bootstrap
...

文件my-scripts.config是一个YAML文件,EBS部署时会执行该文件。它的格式如下:
container_commands:
    01-migration:
        command: "php /var/app/ondeck/artisan --env=staging migrate"
        leader_only: true

将目录和文件添加到git中,提交后运行git aws.push,然后迁移。

.ebextensions中的内容是如何工作的,可以在这里找到说明。

路径/var/app/ondeck是您的应用程序在脚本运行时所在的位置,在此之后它将被复制到/var/app/current中。

Artisan选项--env=staging很有用,可以告诉Artisan它应该在哪个环境下运行,以便从app/config/staging/database.php找到正确的数据库设置。

如果您需要一种快速而简单的方法来记录迁移命令失败的原因,可以尝试类似于"php /var/app/ondeck/artisan --env=staging migrate > /tmp/artisan-migrate.log"的方法,这样您就可以登录到您的EC2实例并检查日志。


@HimelNagRana 我不太明白你的意思,但你可能误解了迁移(应该)如何工作。所有的迁移脚本都应该始终在git仓库中。你的数据库不应该在每次部署时“重置”,迁移应该只执行迁移脚本中up方法中的小改变。查看迁移文档:http://laravel.com/docs/4.2/migrations - oskarth
我认为我没有表达清楚。对此我感到抱歉。我了解迁移的工作原理(或应该如何工作)。这更像是一个与部署相关的问题,我已经弄清楚了怎么做。例如,假设我想将“last_login”添加到用户实体中。然后我会生成迁移并运行它。我的问题是,在部署到ElasticBeanstalk时,我是否需要采取任何特殊措施使迁移运行起来?后来我发现答案是否定的。无论如何,还是要谢谢。 - Himel Nag Rana
@HimelNagRana 我明白了,就像你自己发现的那样,你不需要除了上面的迁移命令之外的任何东西。干杯! - oskarth
我正在尝试使用sequelize在一个node应用程序中实现相同的功能。你可以解释一下leader_only标志吗?这是Amazon EB选项吗?它是否确保迁移仅运行一次? - Manuel
1
@Manuel,文档中有类似的说明:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html(搜索leader_only)。自从我写这个SO Q&A以来,我已经开始在CI环境中执行迁移,所以不再使用这种方法。 - oskarth
显示剩余2条评论

6

oskarth的回答之后,AWS Elastic Beanstalk如何部署新应用程序版本的一些说明可能在过去几年中已经发生了变化。根据与.ebextensions的container_commands相关的AWS文档,如果未设置“cwd”选项,则工作目录是未解压应用程序的暂存目录。这意味着在部署过程中,位于实例下的用户将被定位在/var/app/staging/,其中包含应用程序的提取源版本。因此,artisan命令可以单独执行,也可以按照/var/app/ondeck/路径后跟var/app/staging/的方式执行,如下所示:

container_commands:
01-migration:
    command: "php artisan --env=staging migrate"
    leader_only: true

或者这个
container_commands:
01-migration:
    command: "php /var/app/staging/artisan --env=staging migrate"
    leader_only: true

我已经使用上述两种配置部署了我的项目。在数小时内查看eb-engine.log文件并反复阅读文档后,我发现了这一点。希望其他人在阅读后也不要花费太长时间。可以通过终端上的eb logs命令,在环境控制台或通过与环境关联的S3存储桶访问日志。文档中几乎解释了所有内容。我没有在oskarth的答案中进行评论,因为我还没有被允许!

附注:路径/var/app/staging与Laravel中的暂存环境无关。


2

值得一提的是,如果人们正在使用docker容器在Beanstalk上运行他们的应用程序,则必须在容器内运行此命令。

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

问题是容器名称每次都会更改。
因此,docker ps -qf name=php-fpm 部分只会获取一个包含 php-fpm 的容器名称。因此,请将其替换为其他与您要运行它的容器匹配的内容。
另外,请使用 --force ,否则它将尝试等待提示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接