首页 > 解决方案 > 从 Beanstalk/EC2 Web 应用程序读取/写入 S3 图像

问题描述

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

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

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

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

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

我从这里去哪里?我已经搜索并阅读了所有我能找到的似乎有帮助的东西,但我什么也没有。

标签: amazon-web-servicesamazon-s3amazon-ec2amazon-elastic-beanstalk

解决方案


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

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

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

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

来源

3) 使用 Amazon SDK 创建一个 composer.json 文件并替换为您想要的任何版本。将 composer.json 放在项目文件夹的根目录中。(当您上传项目代码时,Elastic Beanstalk 会为您施展魔法,并将安装所有 composer 包)。

{
    "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) Now finally, after all that fun setup, here is how you can put an image object into S3 when a user uploads a file. Replace BUCKET_NAME with the exact name of your bucket, FILE_NAME.JPG with the destination file name on S3, and PATH/TO/TEMP_FILE.JPG with the temporary path where the image is being stored on your Elastic Beanstalk server.

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

7) Okay, so that handles file writing. Now once you want to show the user the uploaded file, you can do so with a regular tag. Again, replacing all capitalized fields with their correct values:

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

8) You now should have a web application with image write/read capabilities to Amazon S3.


推荐阅读