首页 文章

从Beanstalk / EC2 Web应用程序读取/写入S3映像

提问于
浏览
1

我有一个Web应用程序(Elastic Beanstalk在Linux EC2实例上管理PHP),允许用户上传图像 .

我担心的是,如果我上传我的代码,我首先必须下载所有图像,然后使用我的新代码重新上传它们,如果它们保留在EC2上 . 所以显而易见的解决方案似乎是将图像目录移动到S3 .

到目前为止我发现的方法是挂载驱动器或SDK . 我发现,对于这两种方法,Elastic Beanstalk似乎在写保护的驱动器位置运行,阻止我访问其他方法 .

例如,对于已安装的驱动器,我无法获取足够的目录来访问已安装的驱动器 . Beanstalk在/ var / app / current /中运行,安装的驱动器位于/ var / s3- . 如果我尝试访问它(../../s3-),它会在与我的应用程序相同的文件夹中查找它 .

当我按照SDK的说明进行操作时,我将其安装在ec2-user中 . 所以它位于/home/ec2-user/vendor/autoload.php和以前一样,我也无法访问该文件夹(甚至来自require语句)!

我从哪里开始?我搜索并阅读了我能找到的所有有用的东西,而且我没有得到任何结果 .

2 回答

  • 0

    我不完全确定我理解你的意思是它和你的应用程序在同一文件夹中查找,但这是我从基于PHP的Web应用程序读取/写入S3文件的方法:

    1)为您的应用程序创建一个新存储桶 . 此存储桶可以与管理Elastic Beanstalk项目的存储桶分开 .

    2)在您的存储桶中,转到权限 - >存储桶策略并添加此策略以使您的图像公开 . Important: 将BUCKET_NAME替换为您的存储桶的实际名称

    {
      "Id": "Policy1397632521960",
      "Statement": [
        {
          "Sid": "Stmt1397633323327",
          "Action": [
            "s3:GetObject"
          ],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::BUCKET_NAME/*",
          "Principal": {
            "AWS": [
              "*"
            ]
          }
        }
      ]
    }
    

    Source

    3)使用Amazon SDK创建composer.json文件,并替换为您想要的任何版本 . 将composer.json放在项目文件夹的根目录中 . (当您上传项目代码时,Elastic Beanstalk会为您带来魔力,并将安装所有作曲家程序包) .

    {
        "require": {
            "aws/aws-sdk-php": "3.27.1",
        }
    }
    

    4)将其包含在处理文件上载的PHP文件的顶部 .

    require __DIR__ . '/vendor/autoload.php';
    use Aws\S3\S3Client;
    

    5)使用AWS PHP SDK创建S3Client对象 . 用正确的值替换YOUR_KEY,YOUR_SECRET和YOUR_BUCKET_REGION . 再次,将其添加到同一文件中 .

    $client = S3Client::factory(
         [
             'credentials' =>
              [
                     'key'    => 'YOUR_KEY',
                     'secret' => 'YOUR_SECRET'
                 ],
              'region' => 'YOUR_BUCKET_REGION',
              'version' => 'latest'
             ]
    );
    

    6)最后,在完成所有有趣的设置之后,以下是当用户上传文件时如何将图像对象放入S3 . 将BUCKET_NAME替换为您的存储桶的确切名称,将FILE_NAME.JPG替换为S3上的目标文件名,将PATH / TO / TEMP_FILE.JPG替换为存储在Elastic Beanstalk服务器上的映像的临时路径 .

    $client->putObject([
                        'Bucket' => 'BUCKET_NAME',
                        'Key' => 'FILE_NAME.JPG',
                        'Body' => fopen('PATH/TO/TEMP_FILE.JPG', 'rb'),
                        'ACL' => 'public-read'
                       ]);
    

    7)好的,这样处理文件写入 . 现在,一旦您想向用户显示上传的文件,您就可以使用常规标记 . 同样,用正确的值替换所有大写字段:

    <img src="https://s3-YOUR_BUCKET_REGION.amazonaws.com/BUCKET_NAME/FILE_NAME.JPG" alt="My S3 image">
    

    8)您现在应该拥有一个具有图像写入/读取功能的Web应用程序到Amazon S3 .

  • 0

    这似乎有效,我比其他解决方案更喜欢它:

    我正在使用存储桶权限策略,只允许访问找到的特定URL:https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-4

    这允许我限制对我的图像的访问(至少就我能够尝试的那样),除了来自我的网络主机的那些 . 我仍然会使用API进行文件编写,如果由于某种原因我发现我需要列出一个目录 .

    关于包含composer.json文件的部分,我开始上传,而不是尝试从我的代码中引用autoload.php文件 . 并使用 DIR 作为包含路径 . 如果没有基督徒的帮助,这些都是我不会想到的关键部分 .

相关问题