简体   繁体   中英

app/console assets:install to S3 using stream wrapper errors

I have a stream wrapper configured to work with amazon s3 using the Gaufrette bundle to manage the filesystem. I can successfully dump assets using assetic and my current configuration is as follows:

knp_gaufrette:
    adapters:
        amazon:
            amazon_s3: 
                amazon_s3_id: site_store.s3
                bucket_name: %site_store.bucket_name%
                create: true

    filesystems:
        amazon:
            adapter: amazon

    stream_wrapper:
        protocol: s3
        filesystems:
            - amazon

assetic:
    read_from:      %cdn_path_prod%
    write_to:       %cdn_path_prod%

and my params:

  cdn_url_prod: "http://images.site.com/"
    cdn_path_prod: "s3://amazon"

I was able to do app/console assetic:dump --env=dev. Then it would upload the assets to my s3 buckets successfully. However when I try to do the same with assets install by doing:

app/console assets:install s3://amazon

It gives me this error:

[InvalidArgumentException]  
The specified path (s3://amazon) is invalid.

I've looked over the web and someone was able to do it as he described here . What is wrong with my steam wrapper?

Are you sure that any stream wrapper is regsitered to handle "s3://" scheme ?

In https://github.com/Cybernox/AmazonWebServicesBundle/blob/master/Resources/doc/cdn.md#dump-assets-to-the-s3-bucket , you'll see how they register the stream wrapper to be able to dump assets to a "s3://" target.

So what I've done and it is working.

Add at composer.json and install it

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

Create the class:

<?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();
    }

}

Add the parameters: aws_key , aws_secret_key , aws_region in parameters.yml

Override boot() method at AppKernel.php :

public function boot() {
    parent::boot();
    $s3client = new \Path\to\Amazon\StreamWrapperS3($this->container->getParameter('aws_key'), $this->container->getParameter('aws_secret_key'), $this->container->getParameter('aws_region'));
    $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(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 s3://<your-bucket-name> --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>

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