Search code examples
phpamazon-s3aws-php-sdklocalstack

Can't get list Objects from Localstack s3 bucket using php aws S3Client


I have aws s3 localstack in docker-compose declared as:

version: "3"

services:
...
 localstack:
    image: localstack/localstack
    environment:
      - SERVICES=s3
      - USE_SSL=false
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
    ports:
      - "4572:4572"
      - "4566:4566"
      - "8083:8080"
    networks:
      - mynetwork

After build everything works fine. I am able to connect to the image:

docker exec -ti my-project_localstack_1 /bin/bash

And make a new bucket using command line:

awslocal s3 mb s3://my-bucket

Initially I was able to put new objects into the bucket from my php app. But was not able to see/view list of them from php/postman/browser.

I've made some research and found this solution.

awslocal s3 mb s3://my-bucket

awslocal s3api put-bucket-acl --bucket my-bucket --acl public-read

Now, I am able to get list of objects by prefix in anonymous mode (no credentials or tokens) in my Chrome browser and using Postman.

But I fail to get $s3Client->listObjects(...). It always returns empty result.

Note: I am still able to execute $s3Client->putObject(...). And I checked another commands $s3client->getBucketAcl(...) and $s3Client->getObjectUrl(...). They work fine. What I want to say, connection to the localstack host from php is fine and instance is working and responding fine.

Here is the code on php side that I use to instantiate $s3Client:

class S3
{
    /** @var \Aws\S3\S3Client  */
    private static $client = null;
    private static function init()  // Lazy S3client initiation
    {
        if (is_null (self::$client)) {
            self::$client = new Aws\S3\S3Client ([
                'region'  => 'us-east-1',
                'version' => '2006-03-01',
                'credentials'   => false,
                'endpoint' => "http://localstack:4572",
                'use_path_style_endpoint' => true,
                'debug' => true
            ]);
        }
    }  
    ...
    public static function list_objects($bucket, array $options)
    {
        self::init();

        return self::$client->listObjects([
            'Bucket'    => "my-bucket",
            'Prefix'    => "year/month/folder/",
            'Delimiter' => $options['delimiter'] ? $options['delimiter'] : '/',
        ]);
    }
    ...
}

This method returns @metadata->effectiveUri :

 array (size=2)
    'instance' => string '0000000040d78e4d00000000084dbdb3' (length=32)
    'data' => 
      array (size=1)
        '@metadata' => 
          array (size=4)
            'statusCode' => int 200
            'effectiveUri' => string 'http://localstack:4572/my-bucket?prefix=year%2Fmonth%2Ffolder%2F&delimiter=%2F&encoding-type=url'

If I take this url and run it in browser or postman or php docker terminal curl it returns list of my files. It only returns empty array when I call it though s3Client in php.

I have a feeling that something is wrong with permissions. But since I don't have that much knowledge and experience with aws-s3 service I can't figure that out. And it seem confusing that some "default" permissions allows client to put objects but restrict to read index. And I can read index of objects using browser or curl, but not through the app.

Any ideas?


Solution

  • I've encounted the same problem.
    However, I changed the docker-compose as follows, then I could avoid the problem.

    image: localstack/localstack:0.11.0

    I think it may be a degradation issue of localstack.