我正在使用EC2实例,并且希望将PHP网站与Amazon S3存储桶连接起来,我已经在这里看到了PHP的API:http://aws.amazon.com/sdkforphp/,但尚不清楚。
这是我需要在 Controller 中编辑的代码行:
thisFu['original_img']='/uploads/fufu/'.$_POST['cat'].'/original_'.uniqid('fu_').'.jpg';
我需要连接到Amazon S3并能够更改如下代码:
$thisFu['original_img']='my_s3_bucket/uploads/fufu/'.$_POST['cat'].'/original_'.uniqid('fu_').'.jpg';
我已经为此目的配置了IAM用户,但是我不知道完成该工作所需的所有步骤。
如何连接Amazon S3并与之交互以上传和检索公共(public)图像?
更新
我决定尝试按照建议的方式使用s3fs,因此按照here的说明安装了它(我的操作系统是Ubuntu 14.04)
我从控制台运行:
sudo apt-get install build-essential git libfuse-dev libcurl4-openssl-dev libxml2-dev mime-support automake libtool
sudo apt-get install pkg-config libssl-dev
git clone https://github.com/s3fs-fuse/s3fs-fuse
cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr --with-openssl
make
sudo make install
一切都已正确安装,但下一步是什么?我应该在哪里声明凭证,以及如何在项目中使用此集成?
第2次更新
我创建了一个名为
.passwd-s3fs
的文件,并使用IAM凭据accessKeyId:secretAccessKey
编写了一个代码行。我将其放置在
home/ubuntu
目录中,并使用chmod 600 ~/.passwd-s3fs
赋予其600权限接下来从控制台运行
/usr/bin/s3fs My_S3bucket /uploads/fufu
/uploads/fufu
里面现在有我所有的存储桶文件夹。但是,当我尝试此命令时:s3fs -o nonempty allow_other My_S3bucket /uploads/fufu
我收到此错误消息:
s3fs: unable to access MOUNTPOINT My_S3bucket : No such file or directory
第3次更新
按照建议,我运行此
fusermount -u /uploads/fufu
,之后我检查了fufu文件夹,并且按预期为空。之后,我再次尝试了此命令(还有一个-o):
s3fs -o nonempty -o allow_other My_S3bucket /uploads/fufu
并得到以下错误信息:
fusermount: failed to open /etc/fuse.conf: Permission denied
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
还有其他建议吗?
第4次更新 15年4月18日
在控制台的建议下,我运行
sudo usermod -a -G fuse ubuntu
和sudo vim /etc/fuse.conf
,其中我未注释mount_max = 1000和user_allow_other比我运行s3fs -o nonempty -o allow_other My_S3bucket/uploads/fufu
乍一看没有错误,所以我认为一切都很好,但事实恰恰相反。
我现在有点沮丧,因为我不知道发生了什么,但是我的文件夹
/uploads/fufu
被隐藏了,使用ls -Al
我只能看到这个d????????? ? ? ? ? ? fufu
我不能说它是
sudo rm -r
或-rf
或mv -r
我尝试
/uploads/fufu is a directory
,但是什么也没有。我尝试使用
reboot exit and mount -a
卸载,并且错误消息是fusermount
但是我尝试了sudo vim/etc/mtab,发现了这一行:
fusermount: entry for /uploads/fufu not found in /etc/mtab
有人可以告诉我如何卸载并最终删除此文件夹
s3fs /uploads/fufu fuse.s3fs rw,nosuid,nodev,allow_other 0 0
吗? 最佳答案
尽管“S3fs在最近的版本中非常可靠”,但我可以分享我对s3fs的经验,以及在周期性随机系统崩溃后我们将写操作从直接s3fs挂载文件夹访问转移到aws控制台(也可能是SDK api)的信息。
可能您对图像之类的小文件不会有任何问题,但是当我们尝试写入mp4文件时,肯定会出现问题。因此,系统崩溃之前日志中的最后一条消息是:
kernel: [ 9180.212990] s3fs[29994]: segfault at 0 ip 000000000042b503 sp 00007f09b4abf530 error 4 in s3fs[400000+52000]
随机情况很少见,但这使系统不稳定。
因此,我们决定仍然保持s3fs挂载,但仅将其用于读取访问
下面我展示了如何在没有密码文件的情况下使用AIM凭证挂载s3fs
#!/bin/bash -x
S3_MOUNT_DIR=/media/s3
CACHE_DIR=/var/cache/s3cache
wget http://s3fs.googlecode.com/files/s3fs-1.74.tar.gz
tar xvfz s3fs-1.74.tar.gz
cd s3fs-1.74
./configure
make
make install
mkdir $S3_MOUNT_DIR
mkdir $CACHE_DIR
chmod 0755 $S3_MOUNT_DIR
chmod 0755 $CACHE_DIR
export IAMROLE=`curl http://169.254.169.254/latest/meta-data/iam/security-credentials/`
/usr/local/bin/s3fs $S3_BUCKET $S3_MOUNT_DIR -o iam_role=$IAMROLE,rw,allow_other,use_cache=$CACHE_DIR,uid=222,gid=500
另外,您将需要创建分配了具有附加策略的实例的IAM角色:
{"Statement":[{"Resource":"*","Action":["s3:*"],"Sid":"S3","Effect":"Allow"}],"Version":"2012-10-17"}
在您的情况下,似乎使用php sdk是合理的(其他答案已经有使用示例了),但是您也可以使用aws控制台将图像写入s3:
aws s3 cp /path_to_image/image.jpg s3://your_bucket/path
如果您将创建IAM角色并分配给您的实例,则无需提供任何其他凭据
更新-您的问题的答案:
是的,如果您将IAM分配给ec2实例,那么在代码处,您只需要按以下方式创建客户端:
$s3Client = S3Client::factory();
$bucket = 'my_s3_bucket';
$keyname = $_POST['cat'].'/original_'.uniqid('fu_').'.jpg';
$localFilePath = '/local_path/some_image.jpg';
$result = $s3Client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filePath,
'ACL' => 'public-read',
'ContentType' => 'image/jpeg'
));
unlink($localFilePath);
选项2:如果您不需要文件本地存储阶段,而是将direclt从上传表单中放入:
$s3Client = S3Client::factory();
$bucket = 'my_s3_bucket';
$keyname = $_POST['cat'].'/original_'.uniqid('fu_').'.jpg';
$dataFromFile = file_get_contents($_FILES['uploadedfile']['tmp_name']);
$result = $s3Client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => $dataFromFile,
'ACL' => 'public-read',
));
并获得s3链接(如果您可以公开访问)
$publicUrl = $s3Client->getObjectUrl($bucket, $keyname);
或为私有(private)内容生成签名的URL:
$validTime = '+10 minutes';
$signedUrl = $s3Client->getObjectUrl($bucket, $keyname, $validTime);