Dump Symfony2 assets to Amazon S3

2019-03-08 06:51发布

问题:

I'd like to dump my assets to my s3 bucket in production, after deploying with capifony in Symfony 2. I've found some solution, but don't really find out the best to use.

It's possible the dump the assets with Zend_Service_Amazon_S3 but I think it's a bit overkill to import the Zend framework only for this. - http://permalink.gmane.org/gmane.comp.php.symfony.symfony2/54

I've also found this: https://github.com/symfony/symfony/pull/108, where I can tell AsseticBundle the bucket name, but I didn't found where to provide the key and secret for my aws account.

Can you point out a better solution, or give me some detailed information on the above mentioned ones.

回答1:

So what I've done and it is working.

Add at composer.json and install it

"aws/aws-sdk-php": "2.6.16",

Create a service:

<?php

namespace My\AcmeBundle\Amazon;

use Aws\Common\Aws;

class StreamWrapperS3 {

    protected $s3;

    public function __construct($key, $secret, $region) {

        $aws = array(
            'key'    => $key,
            'secret' => $secret,
            'region' => $region
        );

        $this->s3 = Aws::factory($aws)->get('s3');

    }

    public function registerStreamWrapper() {
        $this->s3->registerStreamWrapper();
    }

}

Declare the service atconfig.yml or including it as a file

services:
    my_amazon_s3:
        class: My\AcmeBundle\Amazon\StreamWrapperS3
        arguments: [%aws_key%, %aws_secret_key%, %aws_region%]

Add the parameters at parameters.yml

Override boot() method at AppKernel.php:

public function boot() {
    parent::boot();
    $s3client = $this->container->get('my_amazon_s3');;
    $s3client->registerStreamWrapper();
}

At config_prod.yml add:

framework:
    templating:
        assets_base_url: https://sa-east-1.amazonaws.com/your-bucket-name
assetic:
    write_to: 's3://your-bucket-name'

Finally add the filter with your assets to rewrite correctly your paths:

{% stylesheets filter='cssrewrite'
    'bundles/...' %}
    <link rel="stylesheet" href="{{ asset_url }}" /> {# asset just to be sure that url will be right #}
{% endstylesheets %}

So each time that you've changed something need to run:

php app/console cache:clear --env=prod
php app/console assets:install --env=prod
php app/console assetic:dump --env=prod

A very important detail that took almost 2 days of my time, you need to update CORS of Amazon S3 to access some files as fonts add inside twitter bootstrap css for example. My CORS permissions are like this:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>


回答2:

Actually you don't really need and probably even shouldn't, put your key in the application code. In Amazon S3 you can specify access by sender, in this case you're production server address.

Take a look at the provided post link: https://forums.aws.amazon.com/thread.jspa?messageID=236066

This would allow you to freely write from that server to your bucket. Remember also to deny access from every other ip.



回答3:

I've also found this: https://github.com/symfony/symfony/pull/108, where I can tell AsseticBundle the bucket name, but I didn't found where to provide the key and secret for my aws account.

This should work - just use the following form when specifying the S3 bucket URL:

# config_prod.yml
assetic:
    write_to: s3://{key}:{secret}@{bucket}/