简体   繁体   English

将Symfony2应用程序部署到AWS Elastic Beanstalk - 部署后缓存清除

[英]Deploying Symfony2 Application to AWS Elastic Beanstalk - Post Deployment Cache Clearing

When deploying a Symfony2 app to Elastic Beanstalk I need to perform a manual cache clear in order for the app to begin functioning. 在将Symfony2应用程序部署到Elastic Beanstalk时,我需要执行手动缓存清除,以便应用程序开始运行。 So, I added a container command to clear the prod cache during deployment. 因此,我在部署期间添加了一个容器命令来清除prod缓存。 The command runs, but I still had to manually clear in order for the app to work. 该命令运行,但我仍然需要手动清除才能使应用程序正常工作。

After some digging around, I found that there are absolute path strings in Symfony2 cache files themselves. 经过一番挖掘后,我发现Symfony2缓存文件中有绝对路径字符串。 The command I added runs "pre-deployment" or before the app files get moved from their staging folder (called '/var/app/ondeck') to their final resting place ('/var/app/current'). 我添加的命令运行“预部署”或在应用程序文件从其临时文件夹(称为“/ var / app / ondeck”)移动到其最终休息位置('/ var / app / current')之前运行。 As a result, the absolute path strings in the cache files are wrong and the app fails to load. 因此,缓存文件中的绝对路径字符串是错误的,并且应用程序无法加载。

Also, the dev environment works fine right away because it rebuilds its own cache automatically. 此外,开发环境可以立即正常工作,因为它会自动重建自己的缓存。 The prod environment is the only one that is affected. prod环境是唯一受影响的环境。

My question(s): 我的问题:

  • Is there a way to run the cache clear command automatically AFTER the code has been moved into place? 有没有办法在代码移动到位后自动运行缓存清除命令?
  • Alternatively, is there some way to get Symfony2 to let you specify a different "base path" for the cache generation? 或者,有没有办法让Symfony2让您为缓存生成指定不同的“基本路径”? That way it could be set up to point to the correct final location. 这样它可以设置为指向正确的最终位置。

Thanks everyone in advance :-) 提前谢谢大家:-)

The problem occurs because the cache is filled in the ondeck environment when the various Symfony commands run at the end of the composer install process and/or your own commands (eg assetic:dump). 出现此问题的原因是,当在编写器安装过程结束时运行各种Symfony命令和/或您自己的命令(例如,assetic:dump)时,缓存在ondeck环境中填充。

The solution is to clear the cache as the last command of the deployment and specify --no-warmup to stop Symfony automatically refilling it, so that the cache is empty when the environment is moved from ondeck to current . 解决方案是将缓存清除为部署的最后一个命令,并指定--no-warmup以停止Symfony自动重新填充它,以便在环境从ondeck移动到当前时缓存为空。 In my .ebextensions/symfony.config I have: 在我的.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

It is not very well documented, but you can also use a post-deployment hook to warm the cache after the environment has been moved to current . 它没有很好的文档记录,但您也可以使用部署后挂钩在环境移动到当前 加热缓存。 Also in .ebextensions/symfony.config : 也在.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      

This problem is fixed in the latest Symfony distributions 2.3.23, 2.5.8, 2.6.1, and upcoming versions (2.7., 3., ...) 在最新的Symfony发行版2.3.23,2.5.8,2.6.1和即将发布的版本(2.7。,3。,...)中修复了此问题。

See https://github.com/heroku/heroku-buildpack-php/issues/64 请参阅https://github.com/heroku/heroku-buildpack-php/issues/64

Symfony will now use links relative to FILE in the container so you don't need to use the post deploy hack anymore. Symfony现在将在容器中使用相对于FILE的链接,因此您不再需要使用post deploy hack。 Note that you still need to install assets as hard links. 请注意,您仍需要将资产安装为硬链接。

I have spent a bit of time trying to get things working a reusable way, here is the ebextensions file that we have finalised. 我花了一些时间尝试以可重用的方式工作,这是我们已经完成的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

I had the same problem and I found solution on this page 我有同样的问题,我在这个页面找到了解决方案

and my final code is - I'm using Symfony Framework (v2.8): 我的最终代码是 - 我正在使用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

Word of explanatioon: 解释的话:

  • I don't need to warm up cache so I do rm -rf on cache and logs folders 我不需要预热缓存,所以我在缓存日志文件夹上执行rm -rf
  • I change cache and logs folders permissions to be 100% sure that they are writable for $EB_CONFIG_APP_USER - in this case webapp user 我将缓存和日志文件夹权限更改为100%确保它们可写为$ EB_CONFIG_APP_USER - 在这种情况下是webapp用户

Tried overriding getCacheDir? 尝试重写getCacheDir?

in app/AppKernel.php: 在app / AppKernel.php中:

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

Based on @rhunwicks answers, here's my .ebextensions/symfony.config : 基于@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

Make sure in your composer there is no "symfony-assets-install": "symlink" to save yourself from spending hours trying to figure out why the symlinks point to /var/app/ondeck/src/BundleName/MyBundle/Resources/public instead of the current folder. 确保你的作曲家没有"symfony-assets-install": "symlink"来节省你自己花费数小时试图弄清楚为什么符号链接指向/var/app/ondeck/src/BundleName/MyBundle/Resources/public而不是current文件夹。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM