简体   繁体   中英

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. So, I added a container command to clear the prod cache during deployment. 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. 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'). 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.

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? 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).

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 . In my .ebextensions/symfony.config I have:

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 :

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

See 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. 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.

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):

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
  • 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

Tried overriding getCacheDir?

in app/AppKernel.php:

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

Based on @rhunwicks answers, here's my .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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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