部署Symfony2应用到AWS弹性Beanstalk - 发布后缓存清除

16
在 Elastic Beanstalk 上部署 Symfony2 应用程序时,我需要手动清除缓存以使应用程序开始运行。因此,在部署过程中添加了一个容器命令来清除生产缓存。该命令已运行,但仍需手动清除才能使应用程序正常工作。
经过一番搜索,我发现在 Symfony2 缓存文件本身中有绝对路径字符串。我添加的命令在应用程序文件从其分段文件夹(称为“/var/app/ondeck”)移动到其最终位置(“/var/app/current”)之前的“预部署”阶段运行。结果,缓存文件中的绝对路径字符串是错误的,导致应用程序无法加载。
此外,开发环境立即正常工作,因为它会自动重建其自己的缓存。只有生产环境受到影响。
我的问题:
  • 是否有办法在代码移动到位后自动运行缓存清除命令?
  • 或者,是否有一种方法可以让Symfony2让您指定缓存生成的不同“基本路径”?这样,它可以设置为指向正确的最终位置。
谢谢大家的帮助 :-)

1
你正在使用最新的5.4 AMI吗?我有完全相同的设置,我没有注意到这个问题,但我会进行一些挖掘...你是使用git部署还是手动上传zip文件? - greg
6个回答

9
问题的出现是因为缓存在各种Symfony命令运行时填充到“ondeck”环境中,在composer安装过程的末尾和/或您自己的命令(例如assetic:dump)中。
解决方案是在部署的最后一个命令中清除缓存,并指定“--no-warmup”以停止Symfony自动重新填充它,以便在从“ondeck”移动到“current”时缓存为空。在我的“.ebextensions / symfony.config”文件中,我有以下设置:
container_commands:
  01_migrate:
    command: php app/console doctrine:migrations:migrate --env=prod --no-debug --no-interaction
    leader_only: true
  02_dumpassets:
    command: php app/console assetic:dump --env=prod --no-debug
  99_clearcache:
    command: php app/console cache:clear --env=prod --no-debug --no-warmup

这个功能没有被很好地记录在文档中,但是当环境已经移动到“当前”之后,你也可以使用后部署钩子来预热缓存。在 .ebextensions/symfony.config 中也可以实现:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/01-cachewarm.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      . /opt/elasticbeanstalk/support/envvars
      cd $EB_CONFIG_APP_CURRENT
      php app/console cache:warmup --env=prod --no-debug      

嗨,我正在尝试按照您描述的方式运行99_clearcache命令,但出现错误“无法打开输入文件:app/console”。您对此有何想法吗?谢谢! - Acyra
1
@Acyra - 我相信你已经解决了这个问题,因为你的评论是一年半前的 :) 但我也遇到了这个问题,所以我会为任何将来可能遇到此问题的人添加一个评论。应用程序路径是 /var/app/current/,但命令是从文件系统根目录操作的,所以我只是在我的命令中使用了绝对路径 /var/app/current/app/console,这似乎有点不太优雅,但完全可以正常工作。 - Darragh Enright
嗨 @Darragh,我认为这只是因为你的应用程序之前的一个版本可以工作,但我想在第一次部署的情况下它不会有效。 - joserobleda
我甚至不记得这个评论了,但是已经注意到了 - 谢谢 :) - Darragh Enright
嗨,我遇到了同样的问题,有点困惑。但是我在哪里可以找到.ebextensions/symfony.config呢?它是在我的项目中某个位置上吗,还是需要我添加它?谢谢大家。 - jofftiquez

3
这个问题已经在最新的Symfony发行版2.3.23、2.5.8、2.6.1和即将发布的版本(2.7,3等)中得到修复。
请参见https://github.com/heroku/heroku-buildpack-php/issues/64 Symfony现在将使用容器中相对于FILE的链接,因此您不再需要使用后部署hack。请注意,您仍然需要安装硬链接作为资产。

这个救了我的一天。我试图执行一个缓存预热命令,但 AWS 返回了一个错误,但是最新版本的 Symfony 不需要它。谢谢! - Hugo Nogueira

1

我曾经遇到同样的问题,后来在this页面上找到了解决方案。

我的最终代码如下 - 我使用的是Symfony Framework(v2.8):

commands:
  01_create_post_dir:
    command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post"
    ignoreErrors: true

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/initial_cron_job.sh":
  mode: "000755"
  owner: root
  group: root
  content: |
    #!/usr/bin/env bash
    # This line was very important for me as I needed to get EnvVars
    . /opt/elasticbeanstalk/support/envvars
    rm -rf /var/app/current/app/cache/* /var/app/current/app/logs/*
    chmod -R 777 /var/app/current/app/cache
    chmod -R 777 /var/app/current/app/logs
    su -c "command_name" $EB_CONFIG_APP_USER

解释:

  • 我不需要预热缓存,所以我会在cachelogs文件夹上运行rm -rf命令
  • 我更改了缓存和日志文件夹的权限,以确保它们可写给$EB_CONFIG_APP_USER - 在这种情况下是webapp用户

1
我花了一些时间尝试以可重用的方式使事情正常运行,这是我们最终确定的 ebextensions 文件。
files:
  "/tmp/parameters.yml":
    mode: "000444"
    content: |
      parameters:
        database_driver: pdo_mysql
        database_host: '...'
        database_port: null
        database_name: ...
        database_user: ...
        database_password: ...
        mailer_transport: smtp
        mailer_host: 127.0.0.1
        mailer_user: null
        mailer_password: null
        locale: en
        secret: ...

option_settings:
  - namespace: aws:elasticbeanstalk:hostmanager
    option_name: LogPublicationControl
    value: true
  - namespace: aws:elasticbeanstalk:container:php:phpini
    option_name: document_root
    value: /web
  - namespace: aws:autoscaling:launchconfiguration # This is for permission to the RDS instance
    option_name: SecurityGroups
    value: ...

container_commands:
  01-params:
    command: cp /tmp/parameters.yml app/config/parameters.yml
  02-params:
    command: chown webapp:webapp app/config/parameters.yml
  03-bootsrap:
    command: php vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php
  04-bootsrap:
    command: chown webapp:webapp app/bootstrap.php.cache
  05-cache:
    command: php app/console cache:clear --env=prod --no-debug --no-warmup
  06-cache:
    command: chmod -R 0777 app/cache
  07-logs:
    command: chmod -R 0777 app/logs
  08-cache:
    command: chown -R webapp:webapp app/cache
  09-logs:
    command: chown -R webapp:webapp app/logs

0

尝试覆盖 getCacheDir 方法?

在 app/AppKernel.php 文件中:

public function getCacheDir()
{
    return "/path/to/the/cache";
}

0

根据 @rhunwicks 的答案,这是我的 .ebextensions/symfony.config 文件:

commands:
  01updateComposer:
    command: export COMPOSER_HOME=/root && /usr/bin/composer.phar self-update

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/01-cachewarm.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      . /opt/elasticbeanstalk/support/envvars
      cd $EB_CONFIG_APP_CURRENT
      php app/console cache:clear --env=prod
      php app/console assetic:dump --env=prod

确保在您的composer中没有“symfony-assets-install”:“symlink”,以免浪费数小时尝试弄清为什么符号链接指向“/var/app/ondeck/src/BundleName/MyBundle/Resources/public”而不是“current”文件夹。


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