概要
ローカルでS3が使えるように環境を作る。
アプリなどから画像をS3に登録してサイト側で閲覧できるようにしたい。
お知らせ
minIOのバージョンがアップされています。
この記事のminIOは1つ前のもの (RELEASE.2021-06-17T00-10-46Z) です。
※ 最新のminIOの場合、異なる部分があると思うのでご注意ください
<参考サイト>
※ MinIOを使ってローカルで外部ストレージをAmazonS3から置き換える
ファイル構成
├ docker
│ └ minio
│ ├ config ... minio設定 (git管理対象外)
│ ├ data ... minioデータ (git管理対象外)
│ ├ export
│ │ └ static ... 起動時に取り込むファイル
│ │ ├ 150x150.png
│ │ └ 640x480.png
│ └ policies
│ └ buckets
│ └ static
│ └ policy.json ... staticバケットのポリシー定義
│
│.gitignore
├ docker-compose.yml
└ REAMDE.md
※ github: https://github.com/reflet/docker-s3
docker設定
minio
を 9090
ポートで起動する設定となっています。
※ 起動時に docker/minio/export/...
を取り込むように設定しています
※ 最新版は仕様が変わっているのでバージョン指定( RELEASE.2021-06-17T00-10-46Z
)しています
version: '3'
services:
minio:
image: minio/minio:RELEASE.2021-06-17T00-10-46Z
container_name: 'minio'
ports:
- 9090:9000
environment:
- MINIO_ACCESS_KEY=minio
- MINIO_SECRET_KEY=minio123
entrypoint: sh
command: -c "
mkdir -p /data/.minio.sys/buckets;
cp -r /policies/* /data/.minio.sys/;
cp -r /export/* /data/;
/usr/bin/minio server /data;
"
volumes:
- ./docker/minio/data:/data
- ./docker/minio/export:/export
- ./docker/minio/config:/root/.minio
- ./docker/minio/policies:/policies
Bucketのポリシー設定
static
バケットのポリシー設定を記述します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::static"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::static/*",
"arn:aws:s3:::static"
]
}
]
}
サーバ起動
下記コマンドにて、dockerコンテナを起動します。
$ docker-compose up -d
管理画面
minioの管理画面へアクセスできます。
※ ID、PASSは、 docker-compose.yml
に記載されています。
$ open http://127.0.0.1:9090/
S3ファイルへアクセス
下記URLにて static
バケットのファイルにアクセス可能です。
※ アプリなどからアクセスする際に指定するURLとなります
$ open http://127.0.0.1:9090/static/hoge.txt
$ open http://127.0.0.1:9090/static/150x150.png
$ open http://127.0.0.1:9090/static/640x480.png
AWS SDK for PHP
AWS SDK for PHP
で使う場合は、以下のようにエンドポイントの指定が必要となります。
※ アクセス元が、docker内のコンテナか、docker外のホストかで「 endpoint
」が変わります
date_default_timezone_set('Asia/Tokyo');
require 'vendor/autoload.php';
$s3 = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'ap-northeast-1',
'credentials' => [
'key' => 'minio',
'secret' => 'minio123',
],
'endpoint' => 'http://minio:9000', // ← 追加 (docker内からアクセス)
// 'endpoint' => 'http://127.0.0.1:9090', // ← 追加 (ホストからアクセス)
'use_path_style_endpoint' => true, // ← 追加
]);
minioのファイル操作 (awscliコマンド)
管理画面から操作できますが、まとめて画像ファイルをアップしたいなどの場合、
aws-cliコマンドで操作した方が楽そうです。
$ aws --version
もし、コマンドが無い場合は追加する。
# MacOS
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ brew -v
$ brew install awscli
$ aws --version
# Ubuntu
$ sudo apt-get -y install unzip
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
$ aws --version
Config設定
プロフィールを作成する。
$ aws configure --profile minio
AWS Access Key ID [None]: minio
AWS Secret Access Key [None]: minio123
Default region name [None]: ap-northeast-1
Default output format [None]: json
プロフィール一覧を確認してみる。
$ aws configure list-profiles
プロフィール(minio)の設定状況を確認してみる。
$ aws configure list --profile minio
バケット内のファイル一覧を確認する
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 ls s3://static
2020-10-25 09:33:53 5 hoge.txt
画像をまとめて転送する
media
フォルダをまとめて static
バケットに送る。
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 sync media s3://static/media
画像をまとめて削除する
media
フォルダを削除する
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 rm s3://static/media/ --recursive
ファイルを追加する
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 cp fuga.txt s3://static
upload: ./hoge.txt to s3://static/fuga.txt
フォルダを追加する
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://172.17.100.101:9090/ s3api put-object --bucket static --key hoge/
ファイルを削除する
# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 rm s3://static/hoge.txt
delete: s3://static/hoge.txt
minioのファイル操作 (curlコマンド)
Linuxサーバであれば、ほぼ存在する「 curlコマンド
」で操作してみる。
ファイルを取得する
# docker内からアクセス: 127.0.0.1:9090 → http://minio:9000
$ curl http://127.0.0.1:9090/static/hoge.txt
ファイルを登録する (認証なし)
「 /tmp/hoge.txt
」を転送する例です。
# docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
$ export FILE='hoge.txt'
$ export URL='http://127.0.0.1:9090/static/${FILE}'
$ export PATH='/tmp/${FILE}'
$ curl -i --request PUT ${URL} \
--upload-file ${PATH} \
-H "x-amz-acl: bucket-owner-full-control"
ファイルを登録する (認証あり)
「 /tmp/hoge.txt
」を転送する例です。
# docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
export S3_KEY="minio"
export S3_SECRET="minio123"
export RESOURCE="/static/hoge.txt"
export CONTENT_TYPE="application/octet-stream"
export DATE=`date -R`
export _SIGNATURE="PUT\n\n${CONTENT_TYPE}\n${DATE}\n${RESOURCE}"
export SIGNATURE=`echo -en ${_SIGNATURE} | openssl sha1 -hmac ${S3_SECRET} -binary | base64`
curl -v -X PUT http://127.0.0.1:9090${RESOURCE} \
-T /tmp/hoge.txt \
-H "Host: 127.0.0.1:9090" \
-H "Date: ${DATE}" \
-H "Content-Type: ${CONTENT_TYPE}" \
-H "Authorization: AWS ${S3_KEY}:${SIGNATURE}"
ファイルを登録する (認証なし - PHP)
PHPで curl_exec()
関数にて送信を試してみる。
$file = '/tmp/hoge.txt';
$fp = fopen($file, 'rb');
$size = filesize($file);
// docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
$url = 'http://127.0.0.1:9090/static/' . basename($file);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['x-amz-acl: bucket-owner-full-control']);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
// 結果を見てみる
var_dump($info, $response)
以上